// emu.cpp : Defines the entry point for the application.
//
//原a600.exe程序结构：
/* 00401000 0000C000 可执行代码
*  0040D000 00001000 只读的已初始化数据
*  0040E000 00006000 已初始化的数据
*  00414000 00002000 资源
*/

#include "stdafx.h"
#include "resource.h"
#include "emu.h"


const CHAR _0040D14C[12][30] = {
    "%s  %s        %s",
    "%s  %s %s     %s#$%s",
    "%s  %s %s %s  %s$%s%s",
    "%s  %s %s     %s$%s%s",
    "%s  %s %s %s  %s($%s%s)",
    "%s  %s %s %s  %s$%s%s,X",
    "%s  %s %s %s  %s$%s%s,Y",
    "%s  %s %s     %s$%s",
    "%s  %s %s     %s$%s,X",
    "%s  %s %s     %s$%s,Y",
    "%s  %s %s     %s($%s,X)",
    "%s  %s %s     %s($%s),Y",
};
const UINT32 _0040D2B4[0x10] = {0, 1, 2, 1, 2, 2, 2, 1, 1, 1, 1, 1, 0, 0xFFFFFFFF, 0, 0x00403683};

char _0040E010[61][8] = {
	"ADC  ", "AND  ", "ASL  ", "ASL  A", "BCC  ", "BCS  ", "BEQ  ", "BIT  ",
	"BMI  ", "BNE  ", "BPL  ", "BRK  ", "BVC  ", "BVS  ", "CLC  ", "CLD  ",
	"CLI  ", "CLV  ", "ASL  ", "CMP  ", "CPX  ", "CPY  ", "DEC  ", "DEX  ",
	"DEY  ", "EOR  ", "INC  ", "INX  ", "INY  ", "JMP  ", "JSR  ", "LDA  ",
	"LDX  ", "LDY  ", "LSR  ", "LSR  A", "NOP  ", "ORA  ", "PHA  ", "PHP  ",
	"PLA  ", "PLP  ", "ROL  ", "ROL  A", "ROR  ", "ROR  A", "RTI  ", "RTS  ",
	"SBC  ", "SEC  ", "SED  ", "SEI  ", "STA  ", "STX  ", "STY  ", "TAX  ",
	"TAY  ", "TSX  ", "TXA  ", "TXS  ", "TYA  "};

int SCREEN_WIDTH = 400;
int SCREEN_HEIGHT = 192;
CHAR szTitle[20] = "A600 emulator V1.1"; // The title bar text

UINT32 _0040E3F8 = 1;
UINT8 _0040E538; // 写Flash Memory阶段
// PRODUCT IDENTIFICATION
UINT8 _0040E53C[0x35] = {0};
UINT8 FlashCommandStage;
CHAR _0040E574[60][10];
UINT32 _0040E7CC[0x100];
UINT32 _0040EBCC[0x100];
HANDLE _0040EFCC[0x20];
HANDLE _0040F1CC[0x20];
UINT8* FileMappingList[0x20];
UINT32 FileMappingQuantity; // 映射的文件数量
UINT8 _0040F5D0[0x100];
RECT _0040F6D0[0x60];
UINT8 _0040FCD0[0x60];
RECT _0040FD30; // 屏幕左侧图标区
RECT _0040FD40[0x60]; // 图标在图片资源上的区域
RECT _00410340; // 屏幕右侧图标区
UINT8* pVideoMemory; // 显存指针
UINT8 pvBitsLcd[1920];
HBITMAP hbmLcd;
HDC hdcLcd;
HBITMAP hbmScreen;
HDC hdcScreen;
HBITMAP hbmResource;
HDC hdcResource;
HINSTANCE hInst; // current instance
HANDLE hEvent;
UINT32 _00410AF4;
UINT32 _00410AFC;
HDC hDC;
UINT32 _00410B04;
HWND hWnd;
RECT _00410B10; // 本程序窗体所在桌面区域
UINT32 _00410B20;
UINT32 _00410B24;
UINT32 _00410B28;
UINT32 _00410B2C;
UINT32 SleepFlag;
UINT32 _00410B38;
UINT32 CycleCounter; // MCU周期计数器
CHAR ProgramDirectory[260]; // 存放程序所在目录
UINT8* pRam;
DWORD NoMappingFileSize;
DWORD _00410C4C;
UINT8* _00410C50[0x20];
UINT8* lpNoMappingFileBuffer;
CHAR NoMappingFileName[260];
UINT32 FlashEndAdr;
UINT8* _00410DDC[0x20][0x10];
UINT32 FlashSize;
UINT8* pFlashMemory;
UINT32 FlashStartAdr;
UINT32 DebugBaseAdr;
UINT32 BankSelected;
UINT32 DebugNumOfBank;
UINT32 _004121FC;
UINT32 _00412200;
UINT32 _00412204; // 立即数
struct CPU
{
	UINT32 A;
	UINT32 S;
	UINT32 X;
	UINT32 Y;
	UINT32 P;
	UINT32 PC;
}cpu;
UINT32 AbsoluteAddress;
UINT32 BankAddressList[0x10]; // Bank 映射表
void (*_00412268)();
void (*_0041226C)();
void (*_00412270[0x100])(); // 指令指针
void (*_00412670[0x100])(); // 指令地址模式指针
UINT32 _00412A70[0x100]; // 指令周期数表
UINT32 _00413A70;
UINT32 _00413A74;
UINT32 _00413A78; // opcode
UINT32 Timer1Counter;
UINT32 Timer2Counter;
UINT32 Timer3Counter;
UINT32 Timer4Counter;
UINT32 UniversalTimerCounter;
UINT32 bWantInt; // 中断标志，为1有中断发生
void (*pInterruptHandle[2])();
void (*_004115FC[0x300])(); // 读寄存器响应函数指针
void (*_00412E70[0x300])(); // 写寄存器响应函数指针

#ifdef _DEBUG
// 调试用变量
struct _REGEDIT
{
	UINT32 A;
	UINT32 S;
	UINT32 X;
	UINT32 Y;
	UINT32 P;
	UINT32 PC;
	UINT32 opcode;
	UINT8 datas[3];
	UINT32 counter;
} regedits[0x100];
UINT8 regedits_index = 0;
#endif

// 返回机器型号，1为A600，2MB Flash
UINT32 _00401000()
{
    return 1;
}

// done
void _0040100A()
{
    FlashCommandStage = 0x00;
    _0040E538 = 0x01;

	// CFI QUERY IDENTIFICATION STRING
    _0040E53C[0x10] = 0x51;
    _0040E53C[0x11] = 0x52;
    _0040E53C[0x12] = 0x59;
    _0040E53C[0x13] = 0x01;
    _0040E53C[0x14] = 0x07;
    _0040E53C[0x15] = 0x00;
    _0040E53C[0x16] = 0x00;
    _0040E53C[0x17] = 0x00;
    _0040E53C[0x18] = 0x00;
    _0040E53C[0x19] = 0x00;
    _0040E53C[0x1A] = 0x00;
	// SYSTEM INTERFACE INFORMATION
    _0040E53C[0x1B] = 0x27;
    _0040E53C[0x1C] = 0x36;
    _0040E53C[0x1D] = 0x00;
    _0040E53C[0x1E] = 0x00;
    _0040E53C[0x1F] = 0x04;
    _0040E53C[0x20] = 0x00;
    _0040E53C[0x21] = 0x04;
    _0040E53C[0x22] = 0x06;
    _0040E53C[0x23] = 0x01;
    _0040E53C[0x24] = 0x00;
    _0040E53C[0x25] = 0x01;
    _0040E53C[0x26] = 0x01;
	// DEVICE GEOMETRY INFORMATION
    _0040E53C[0x27] = 0x15; // 1<<0x15 = 2 MB
    _0040E53C[0x28] = 0x00;
    _0040E53C[0x29] = 0x00;
    _0040E53C[0x2A] = 0x00;
    _0040E53C[0x2B] = 0x00;
    _0040E53C[0x2C] = 0x02;
    _0040E53C[0x2D] = 0xFF;
    _0040E53C[0x2E] = 0x01; // 0x01FF+1 = 512 sectors
    _0040E53C[0x2F] = 0x10;
    _0040E53C[0x30] = 0x00; // 0x0010*256 = 4 KB/sector
    _0040E53C[0x31] = 0x1F;
    _0040E53C[0x32] = 0x00; // 0x001F+1 = 32 blocks
    _0040E53C[0x33] = 0x00;
    _0040E53C[0x34] = 0x01; // 0x0100*256 = 64KB/block
}

// 从Flash读一个字节
UINT8 ReadFlash(UINT32 v1)
{
    if ((FlashCommandStage == 0) || (FlashCommandStage == 1))
    {
        return pFlashMemory[v1];
    }
    else
    {
        return _0040E53C[v1];
    }
}

// todo
void WriteFlash(UINT32 addr, UINT8 data)
{
    switch (_0040E538-1)
    {
    case 0://1180
        if ((addr == 0x5555) && (data == 0xAA))
        {
            _0040E538++;
        }
        if (data == 0xF0)
        {
			// Software ID Exit/CFI Exit
            FlashCommandStage = 0;
        }
        break;
    case 1://11C4
    case 4://11C4
        if ((addr == 0x2AAA) && (data == 0x55))
        {
            _0040E538 += 1;
        }
        break;
    case 2://11EE
        if (addr != 0x5555)
        {
			return;
		}
        switch (data-0x90)
        {
        case 0x10://122B Word-Program
            FlashCommandStage = 1;
            break;
        case 0x00://1234 Software ID Entry
            FlashCommandStage = 2;
            _0040E538 = 0;
            break;
        case 0x08://1244 CFI Query Entry
            FlashCommandStage = 3;
            _0040E538 = 0;
            break;
        case 0x60://1254 Software ID Exit/CFI Exit
            FlashCommandStage = 0;
            _0040E538 = 0;
            break;
        }
        _0040E538 += 1;
        break;
    case 3://1273
        if (FlashCommandStage == 1)
        { // Word-Program
            pFlashMemory[addr] = data;
            FlashCommandStage = 0;
            _0040E538 = 1;
        }
        else if ((addr == 0x5555) && (data == 0xAA))
        {
            _0040E538 += 1;
        }
        break;
    case 5://12CC
        switch (data)
		{
        case 0x10: // Chip-Erase
            memset(pFlashMemory, 0xFF, 0x200000);  // Erase 2MB
			break;
        case 0x30: // Sector-Erase
            memset(pFlashMemory+(addr&0x1FF000), 0xFF, 0x1000); // Erase 4KB
			break;
        case 0x50: // Block-Erase
            memset(pFlashMemory+(addr&0x1F0000), 0xFF, 0x10000); // Erase 64KB
			break;
        }
        FlashCommandStage = 0;
        _0040E538 = 1;
        break;
    }
}

// done
void _004013F0()
{
    _0040E7CC[0x00] = 0x0B;
    _0040EBCC[0x00] = 0x00;
    _0040E7CC[0x01] = 0x24;
    _0040EBCC[0x01] = 0x0A;
    _0040E7CC[0x02] = 0x0B;
    _0040EBCC[0x02] = 0x00;
    _0040E7CC[0x03] = 0x0B;
    _0040EBCC[0x03] = 0x00;
    _0040E7CC[0x04] = 0x0B;
    _0040EBCC[0x04] = 0x00;
    _0040E7CC[0x05] = 0x24;
    _0040EBCC[0x05] = 0x07;
    _0040E7CC[0x06] = 0x02;
    _0040EBCC[0x06] = 0x07;
    _0040E7CC[0x07] = 0x0B;
    _0040EBCC[0x07] = 0x00;
    _0040E7CC[0x08] = 0x26;
    _0040EBCC[0x08] = 0x00;
    _0040E7CC[0x09] = 0x24;
    _0040EBCC[0x09] = 0x01;
    _0040E7CC[0x0A] = 0x03;
    _0040EBCC[0x0A] = 0x00;
    _0040E7CC[0x0B] = 0x0B;
    _0040EBCC[0x0B] = 0x00;
    _0040E7CC[0x0C] = 0x0B;
    _0040EBCC[0x0C] = 0x00;
    _0040E7CC[0x0D] = 0x24;
    _0040EBCC[0x0D] = 0x02;
    _0040E7CC[0x0E] = 0x02;
    _0040EBCC[0x0E] = 0x02;
    _0040E7CC[0x0F] = 0x0B;
    _0040EBCC[0x0F] = 0x00;
    _0040E7CC[0x10] = 0x0A;
    _0040EBCC[0x10] = 0x03;
    _0040E7CC[0x11] = 0x24;
    _0040EBCC[0x11] = 0x0B;
    _0040E7CC[0x12] = 0x0B;
    _0040EBCC[0x12] = 0x00;
    _0040E7CC[0x13] = 0x0B;
    _0040EBCC[0x13] = 0x00;
    _0040E7CC[0x14] = 0x0B;
    _0040EBCC[0x14] = 0x00;
    _0040E7CC[0x15] = 0x24;
    _0040EBCC[0x15] = 0x08;
    _0040E7CC[0x16] = 0x02;
    _0040EBCC[0x16] = 0x08;
    _0040E7CC[0x17] = 0x0B;
    _0040EBCC[0x17] = 0x00;
    _0040E7CC[0x18] = 0x0E;
    _0040EBCC[0x18] = 0x00;
    _0040E7CC[0x19] = 0x24;
    _0040EBCC[0x19] = 0x06;
    _0040E7CC[0x1A] = 0x0B;
    _0040EBCC[0x1A] = 0x00;
    _0040E7CC[0x1B] = 0x0B;
    _0040EBCC[0x1B] = 0x00;
    _0040E7CC[0x1C] = 0x0B;
    _0040EBCC[0x1C] = 0x00;
    _0040E7CC[0x1D] = 0x24;
    _0040EBCC[0x1D] = 0x05;
    _0040E7CC[0x1E] = 0x02;
    _0040EBCC[0x1E] = 0x05;
    _0040E7CC[0x1F] = 0x0B;
    _0040EBCC[0x1F] = 0x00;
    _0040E7CC[0x20] = 0x1D;
    _0040EBCC[0x20] = 0x02;
    _0040E7CC[0x21] = 0x01;
    _0040EBCC[0x21] = 0x0A;
    _0040E7CC[0x22] = 0x0B;
    _0040EBCC[0x22] = 0x00;
    _0040E7CC[0x23] = 0x0B;
    _0040EBCC[0x23] = 0x00;
    _0040E7CC[0x24] = 0x07;
    _0040EBCC[0x24] = 0x07;
    _0040E7CC[0x25] = 0x01;
    _0040EBCC[0x25] = 0x07;
    _0040E7CC[0x26] = 0x29;
    _0040EBCC[0x26] = 0x07;
    _0040E7CC[0x27] = 0x0B;
    _0040EBCC[0x27] = 0x00;
    _0040E7CC[0x28] = 0x28;
    _0040EBCC[0x28] = 0x00;
    _0040E7CC[0x29] = 0x01;
    _0040EBCC[0x29] = 0x01;
    _0040E7CC[0x2A] = 0x2A;
    _0040EBCC[0x2A] = 0x00;
    _0040E7CC[0x2B] = 0x0B;
    _0040EBCC[0x2B] = 0x00;
    _0040E7CC[0x2C] = 0x07;
    _0040EBCC[0x2C] = 0x02;
    _0040E7CC[0x2D] = 0x01;
    _0040EBCC[0x2D] = 0x02;
    _0040E7CC[0x2E] = 0x29;
    _0040EBCC[0x2E] = 0x02;
    _0040E7CC[0x2F] = 0x0B;
    _0040EBCC[0x2F] = 0x00;
    _0040E7CC[0x30] = 0x08;
    _0040EBCC[0x30] = 0x03;
    _0040E7CC[0x31] = 0x01;
    _0040EBCC[0x31] = 0x0B;
    _0040E7CC[0x32] = 0x0B;
    _0040EBCC[0x32] = 0x00;
    _0040E7CC[0x33] = 0x0B;
    _0040EBCC[0x33] = 0x00;
    _0040E7CC[0x34] = 0x07;
    _0040EBCC[0x34] = 0x08;
    _0040E7CC[0x35] = 0x01;
    _0040EBCC[0x35] = 0x08;
    _0040E7CC[0x36] = 0x29;
    _0040EBCC[0x36] = 0x08;
    _0040E7CC[0x37] = 0x0B;
    _0040EBCC[0x37] = 0x00;
    _0040E7CC[0x38] = 0x30;
    _0040EBCC[0x38] = 0x00;
    _0040E7CC[0x39] = 0x01;
    _0040EBCC[0x39] = 0x06;
    _0040E7CC[0x3A] = 0x0B;
    _0040EBCC[0x3A] = 0x00;
    _0040E7CC[0x3B] = 0x0B;
    _0040EBCC[0x3B] = 0x00;
    _0040E7CC[0x3C] = 0x07;
    _0040EBCC[0x3C] = 0x05;
    _0040E7CC[0x3D] = 0x01;
    _0040EBCC[0x3D] = 0x05;
    _0040E7CC[0x3E] = 0x29;
    _0040EBCC[0x3E] = 0x05;
    _0040E7CC[0x3F] = 0x0B;
    _0040EBCC[0x3F] = 0x00;
    _0040E7CC[0x40] = 0x2D;
    _0040EBCC[0x40] = 0x00;
    _0040E7CC[0x41] = 0x18;
    _0040EBCC[0x41] = 0x0A;
    _0040E7CC[0x42] = 0x0B;
    _0040EBCC[0x42] = 0x00;
    _0040E7CC[0x43] = 0x0B;
    _0040EBCC[0x43] = 0x00;
    _0040E7CC[0x44] = 0x0B;
    _0040EBCC[0x44] = 0x00;
    _0040E7CC[0x45] = 0x18;
    _0040EBCC[0x45] = 0x07;
    _0040E7CC[0x46] = 0x21;
    _0040EBCC[0x46] = 0x07;
    _0040E7CC[0x47] = 0x0B;
    _0040EBCC[0x47] = 0x00;
    _0040E7CC[0x48] = 0x25;
    _0040EBCC[0x48] = 0x00;
    _0040E7CC[0x49] = 0x18;
    _0040EBCC[0x49] = 0x01;
    _0040E7CC[0x4A] = 0x22;
    _0040EBCC[0x4A] = 0x00;
    _0040E7CC[0x4B] = 0x0B;
    _0040EBCC[0x4B] = 0x00;
    _0040E7CC[0x4C] = 0x1C;
    _0040EBCC[0x4C] = 0x02;
    _0040E7CC[0x4D] = 0x18;
    _0040EBCC[0x4D] = 0x02;
    _0040E7CC[0x4E] = 0x21;
    _0040EBCC[0x4E] = 0x02;
    _0040E7CC[0x4F] = 0x0B;
    _0040EBCC[0x4F] = 0x00;
    _0040E7CC[0x50] = 0x0C;
    _0040EBCC[0x50] = 0x03;
    _0040E7CC[0x51] = 0x18;
    _0040EBCC[0x51] = 0x0B;
    _0040E7CC[0x52] = 0x0B;
    _0040EBCC[0x52] = 0x00;
    _0040E7CC[0x53] = 0x0B;
    _0040EBCC[0x53] = 0x00;
    _0040E7CC[0x54] = 0x0B;
    _0040EBCC[0x54] = 0x00;
    _0040E7CC[0x55] = 0x18;
    _0040EBCC[0x55] = 0x08;
    _0040E7CC[0x56] = 0x21;
    _0040EBCC[0x56] = 0x08;
    _0040E7CC[0x57] = 0x0B;
    _0040EBCC[0x57] = 0x00;
    _0040E7CC[0x58] = 0x10;
    _0040EBCC[0x58] = 0x00;
    _0040E7CC[0x59] = 0x18;
    _0040EBCC[0x59] = 0x06;
    _0040E7CC[0x5A] = 0x0B;
    _0040EBCC[0x5A] = 0x00;
    _0040E7CC[0x5B] = 0x0B;
    _0040EBCC[0x5B] = 0x00;
    _0040E7CC[0x5C] = 0x0B;
    _0040EBCC[0x5C] = 0x00;
    _0040E7CC[0x5D] = 0x18;
    _0040EBCC[0x5D] = 0x05;
    _0040E7CC[0x5E] = 0x21;
    _0040EBCC[0x5E] = 0x05;
    _0040E7CC[0x5F] = 0x0B;
    _0040EBCC[0x5F] = 0x00;
    _0040E7CC[0x60] = 0x2E;
    _0040EBCC[0x60] = 0x00;
    _0040E7CC[0x61] = 0x00;
    _0040EBCC[0x61] = 0x0A;
    _0040E7CC[0x62] = 0x0B;
    _0040EBCC[0x62] = 0x00;
    _0040E7CC[0x63] = 0x0B;
    _0040EBCC[0x63] = 0x00;
    _0040E7CC[0x64] = 0x0B;
    _0040EBCC[0x64] = 0x00;
    _0040E7CC[0x65] = 0x00;
    _0040EBCC[0x65] = 0x07;
    _0040E7CC[0x66] = 0x2B;
    _0040EBCC[0x66] = 0x07;
    _0040E7CC[0x67] = 0x0B;
    _0040EBCC[0x67] = 0x00;
    _0040E7CC[0x68] = 0x27;
    _0040EBCC[0x68] = 0x00;
    _0040E7CC[0x69] = 0x00;
    _0040EBCC[0x69] = 0x01;
    _0040E7CC[0x6A] = 0x2C;
    _0040EBCC[0x6A] = 0x00;
    _0040E7CC[0x6B] = 0x0B;
    _0040EBCC[0x6B] = 0x00;
    _0040E7CC[0x6C] = 0x1C;
    _0040EBCC[0x6C] = 0x04;
    _0040E7CC[0x6D] = 0x00;
    _0040EBCC[0x6D] = 0x02;
    _0040E7CC[0x6E] = 0x2B;
    _0040EBCC[0x6E] = 0x02;
    _0040E7CC[0x6F] = 0x0B;
    _0040EBCC[0x6F] = 0x00;
    _0040E7CC[0x70] = 0x0D;
    _0040EBCC[0x70] = 0x03;
    _0040E7CC[0x71] = 0x00;
    _0040EBCC[0x71] = 0x0B;
    _0040E7CC[0x72] = 0x0B;
    _0040EBCC[0x72] = 0x00;
    _0040E7CC[0x73] = 0x0B;
    _0040EBCC[0x73] = 0x00;
    _0040E7CC[0x74] = 0x0B;
    _0040EBCC[0x74] = 0x00;
    _0040E7CC[0x75] = 0x00;
    _0040EBCC[0x75] = 0x08;
    _0040E7CC[0x76] = 0x2B;
    _0040EBCC[0x76] = 0x08;
    _0040E7CC[0x77] = 0x0B;
    _0040EBCC[0x77] = 0x00;
    _0040E7CC[0x78] = 0x32;
    _0040EBCC[0x78] = 0x00;
    _0040E7CC[0x79] = 0x00;
    _0040EBCC[0x79] = 0x06;
    _0040E7CC[0x7A] = 0x0B;
    _0040EBCC[0x7A] = 0x00;
    _0040E7CC[0x7B] = 0x0B;
    _0040EBCC[0x7B] = 0x00;
    _0040E7CC[0x7C] = 0x0B;
    _0040EBCC[0x7C] = 0x00;
    _0040E7CC[0x7D] = 0x00;
    _0040EBCC[0x7D] = 0x05;
    _0040E7CC[0x7E] = 0x2B;
    _0040EBCC[0x7E] = 0x05;
    _0040E7CC[0x7F] = 0x0B;
    _0040EBCC[0x7F] = 0x00;
    _0040E7CC[0x80] = 0x0B;
    _0040EBCC[0x80] = 0x03;
    _0040E7CC[0x81] = 0x33;
    _0040EBCC[0x81] = 0x0A;
    _0040E7CC[0x82] = 0x0B;
    _0040EBCC[0x82] = 0x00;
    _0040E7CC[0x83] = 0x0B;
    _0040EBCC[0x83] = 0x00;
    _0040E7CC[0x84] = 0x35;
    _0040EBCC[0x84] = 0x07;
    _0040E7CC[0x85] = 0x33;
    _0040EBCC[0x85] = 0x07;
    _0040E7CC[0x86] = 0x34;
    _0040EBCC[0x86] = 0x07;
    _0040E7CC[0x87] = 0x0B;
    _0040EBCC[0x87] = 0x00;
    _0040E7CC[0x88] = 0x17;
    _0040EBCC[0x88] = 0x00;
    _0040E7CC[0x89] = 0x07;
    _0040EBCC[0x89] = 0x01;
    _0040E7CC[0x8A] = 0x39;
    _0040EBCC[0x8A] = 0x00;
    _0040E7CC[0x8B] = 0x0B;
    _0040EBCC[0x8B] = 0x00;
    _0040E7CC[0x8C] = 0x35;
    _0040EBCC[0x8C] = 0x02;
    _0040E7CC[0x8D] = 0x33;
    _0040EBCC[0x8D] = 0x02;
    _0040E7CC[0x8E] = 0x34;
    _0040EBCC[0x8E] = 0x02;
    _0040E7CC[0x8F] = 0x0B;
    _0040EBCC[0x8F] = 0x00;
    _0040E7CC[0x90] = 0x04;
    _0040EBCC[0x90] = 0x03;
    _0040E7CC[0x91] = 0x33;
    _0040EBCC[0x91] = 0x0B;
    _0040E7CC[0x92] = 0x0B;
    _0040EBCC[0x92] = 0x00;
    _0040E7CC[0x93] = 0x0B;
    _0040EBCC[0x93] = 0x00;
    _0040E7CC[0x94] = 0x35;
    _0040EBCC[0x94] = 0x08;
    _0040E7CC[0x95] = 0x33;
    _0040EBCC[0x95] = 0x08;
    _0040E7CC[0x96] = 0x34;
    _0040EBCC[0x96] = 0x09;
    _0040E7CC[0x97] = 0x0B;
    _0040EBCC[0x97] = 0x00;
    _0040E7CC[0x98] = 0x3B;
    _0040EBCC[0x98] = 0x00;
    _0040E7CC[0x99] = 0x33;
    _0040EBCC[0x99] = 0x06;
    _0040E7CC[0x9A] = 0x3A;
    _0040EBCC[0x9A] = 0x00;
    _0040E7CC[0x9B] = 0x0B;
    _0040EBCC[0x9B] = 0x00;
    _0040E7CC[0x9C] = 0x0B;
    _0040EBCC[0x9C] = 0x00;
    _0040E7CC[0x9D] = 0x33;
    _0040EBCC[0x9D] = 0x05;
    _0040E7CC[0x9E] = 0x0B;
    _0040EBCC[0x9E] = 0x00;
    _0040E7CC[0x9F] = 0x0B;
    _0040EBCC[0x9F] = 0x00;
    _0040E7CC[0xA0] = 0x20;
    _0040EBCC[0xA0] = 0x01;
    _0040E7CC[0xA1] = 0x1E;
    _0040EBCC[0xA1] = 0x0A;
    _0040E7CC[0xA2] = 0x1F;
    _0040EBCC[0xA2] = 0x01;
    _0040E7CC[0xA3] = 0x0B;
    _0040EBCC[0xA3] = 0x00;
    _0040E7CC[0xA4] = 0x20;
    _0040EBCC[0xA4] = 0x07;
    _0040E7CC[0xA5] = 0x1E;
    _0040EBCC[0xA5] = 0x07;
    _0040E7CC[0xA6] = 0x1F;
    _0040EBCC[0xA6] = 0x07;
    _0040E7CC[0xA7] = 0x0B;
    _0040EBCC[0xA7] = 0x00;
    _0040E7CC[0xA8] = 0x37;
    _0040EBCC[0xA8] = 0x00;
    _0040E7CC[0xA9] = 0x1E;
    _0040EBCC[0xA9] = 0x01;
    _0040E7CC[0xAA] = 0x36;
    _0040EBCC[0xAA] = 0x00;
    _0040E7CC[0xAB] = 0x0B;
    _0040EBCC[0xAB] = 0x00;
    _0040E7CC[0xAC] = 0x20;
    _0040EBCC[0xAC] = 0x02;
    _0040E7CC[0xAD] = 0x1E;
    _0040EBCC[0xAD] = 0x02;
    _0040E7CC[0xAE] = 0x1F;
    _0040EBCC[0xAE] = 0x02;
    _0040E7CC[0xAF] = 0x0B;
    _0040EBCC[0xAF] = 0x00;
    _0040E7CC[0xB0] = 0x05;
    _0040EBCC[0xB0] = 0x03;
    _0040E7CC[0xB1] = 0x1E;
    _0040EBCC[0xB1] = 0x0B;
    _0040E7CC[0xB2] = 0x0B;
    _0040EBCC[0xB2] = 0x00;
    _0040E7CC[0xB3] = 0x0B;
    _0040EBCC[0xB3] = 0x00;
    _0040E7CC[0xB4] = 0x20;
    _0040EBCC[0xB4] = 0x08;
    _0040E7CC[0xB5] = 0x1E;
    _0040EBCC[0xB5] = 0x08;
    _0040E7CC[0xB6] = 0x1F;
    _0040EBCC[0xB6] = 0x09;
    _0040E7CC[0xB7] = 0x0B;
    _0040EBCC[0xB7] = 0x00;
    _0040E7CC[0xB8] = 0x11;
    _0040EBCC[0xB8] = 0x00;
    _0040E7CC[0xB9] = 0x1E;
    _0040EBCC[0xB9] = 0x06;
    _0040E7CC[0xBA] = 0x38;
    _0040EBCC[0xBA] = 0x00;
    _0040E7CC[0xBB] = 0x0B;
    _0040EBCC[0xBB] = 0x00;
    _0040E7CC[0xBC] = 0x20;
    _0040EBCC[0xBC] = 0x05;
    _0040E7CC[0xBD] = 0x1E;
    _0040EBCC[0xBD] = 0x05;
    _0040E7CC[0xBE] = 0x1F;
    _0040EBCC[0xBE] = 0x06;
    _0040E7CC[0xBF] = 0x0B;
    _0040EBCC[0xBF] = 0x00;
    _0040E7CC[0xC0] = 0x14;
    _0040EBCC[0xC0] = 0x01;
    _0040E7CC[0xC1] = 0x12;
    _0040EBCC[0xC1] = 0x0A;
    _0040E7CC[0xC2] = 0x0B;
    _0040EBCC[0xC2] = 0x00;
    _0040E7CC[0xC3] = 0x0B;
    _0040EBCC[0xC3] = 0x00;
    _0040E7CC[0xC4] = 0x14;
    _0040EBCC[0xC4] = 0x07;
    _0040E7CC[0xC5] = 0x12;
    _0040EBCC[0xC5] = 0x07;
    _0040E7CC[0xC6] = 0x15;
    _0040EBCC[0xC6] = 0x07;
    _0040E7CC[0xC7] = 0x0B;
    _0040EBCC[0xC7] = 0x00;
    _0040E7CC[0xC8] = 0x1B;
    _0040EBCC[0xC8] = 0x00;
    _0040E7CC[0xC9] = 0x12;
    _0040EBCC[0xC9] = 0x01;
    _0040E7CC[0xCA] = 0x16;
    _0040EBCC[0xCA] = 0x00;
    _0040E7CC[0xCB] = 0x0B;
    _0040EBCC[0xCB] = 0x00;
    _0040E7CC[0xCC] = 0x14;
    _0040EBCC[0xCC] = 0x02;
    _0040E7CC[0xCD] = 0x12;
    _0040EBCC[0xCD] = 0x02;
    _0040E7CC[0xCE] = 0x15;
    _0040EBCC[0xCE] = 0x02;
    _0040E7CC[0xCF] = 0x0B;
    _0040EBCC[0xCF] = 0x00;
    _0040E7CC[0xD0] = 0x09;
    _0040EBCC[0xD0] = 0x03;
    _0040E7CC[0xD1] = 0x12;
    _0040EBCC[0xD1] = 0x0B;
    _0040E7CC[0xD2] = 0x0B;
    _0040EBCC[0xD2] = 0x00;
    _0040E7CC[0xD3] = 0x0B;
    _0040EBCC[0xD3] = 0x00;
    _0040E7CC[0xD4] = 0x0B;
    _0040EBCC[0xD4] = 0x00;
    _0040E7CC[0xD5] = 0x12;
    _0040EBCC[0xD5] = 0x08;
    _0040E7CC[0xD6] = 0x15;
    _0040EBCC[0xD6] = 0x08;
    _0040E7CC[0xD7] = 0x0B;
    _0040EBCC[0xD7] = 0x00;
    _0040E7CC[0xD8] = 0x0F;
    _0040EBCC[0xD8] = 0x00;
    _0040E7CC[0xD9] = 0x12;
    _0040EBCC[0xD9] = 0x06;
    _0040E7CC[0xDA] = 0x0B;
    _0040EBCC[0xDA] = 0x00;
    _0040E7CC[0xDB] = 0x0B;
    _0040EBCC[0xDB] = 0x00;
    _0040E7CC[0xDC] = 0x0B;
    _0040EBCC[0xDC] = 0x00;
    _0040E7CC[0xDD] = 0x12;
    _0040EBCC[0xDD] = 0x05;
    _0040E7CC[0xDE] = 0x15;
    _0040EBCC[0xDE] = 0x05;
    _0040E7CC[0xDF] = 0x0B;
    _0040EBCC[0xDF] = 0x00;
    _0040E7CC[0xE0] = 0x13;
    _0040EBCC[0xE0] = 0x01;
    _0040E7CC[0xE1] = 0x2F;
    _0040EBCC[0xE1] = 0x0A;
    _0040E7CC[0xE2] = 0x0B;
    _0040EBCC[0xE2] = 0x00;
    _0040E7CC[0xE3] = 0x0B;
    _0040EBCC[0xE3] = 0x00;
    _0040E7CC[0xE4] = 0x13;
    _0040EBCC[0xE4] = 0x07;
    _0040E7CC[0xE5] = 0x2F;
    _0040EBCC[0xE5] = 0x07;
    _0040E7CC[0xE6] = 0x19;
    _0040EBCC[0xE6] = 0x07;
    _0040E7CC[0xE7] = 0x0B;
    _0040EBCC[0xE7] = 0x00;
    _0040E7CC[0xE8] = 0x1A;
    _0040EBCC[0xE8] = 0x00;
    _0040E7CC[0xE9] = 0x2F;
    _0040EBCC[0xE9] = 0x01;
    _0040E7CC[0xEA] = 0x23;
    _0040EBCC[0xEA] = 0x00;
    _0040E7CC[0xEB] = 0x0B;
    _0040EBCC[0xEB] = 0x00;
    _0040E7CC[0xEC] = 0x13;
    _0040EBCC[0xEC] = 0x02;
    _0040E7CC[0xED] = 0x2F;
    _0040EBCC[0xED] = 0x02;
    _0040E7CC[0xEE] = 0x19;
    _0040EBCC[0xEE] = 0x02;
    _0040E7CC[0xEF] = 0x0B;
    _0040EBCC[0xEF] = 0x00;
    _0040E7CC[0xF0] = 0x06;
    _0040EBCC[0xF0] = 0x03;
    _0040E7CC[0xF1] = 0x2F;
    _0040EBCC[0xF1] = 0x0B;
    _0040E7CC[0xF2] = 0x0B;
    _0040EBCC[0xF2] = 0x00;
    _0040E7CC[0xF3] = 0x0B;
    _0040EBCC[0xF3] = 0x00;
    _0040E7CC[0xF4] = 0x0B;
    _0040EBCC[0xF4] = 0x00;
    _0040E7CC[0xF5] = 0x2F;
    _0040EBCC[0xF5] = 0x08;
    _0040E7CC[0xF6] = 0x19;
    _0040EBCC[0xF6] = 0x08;
    _0040E7CC[0xF7] = 0x0B;
    _0040EBCC[0xF7] = 0x00;
    _0040E7CC[0xF8] = 0x31;
    _0040EBCC[0xF8] = 0x00;
    _0040E7CC[0xF9] = 0x2F;
    _0040EBCC[0xF9] = 0x06;
    _0040E7CC[0xFA] = 0x0B;
    _0040EBCC[0xFA] = 0x00;
    _0040E7CC[0xFB] = 0x0B;
    _0040EBCC[0xFB] = 0x00;
    _0040E7CC[0xFC] = 0x0B;
    _0040EBCC[0xFC] = 0x00;
    _0040E7CC[0xFD] = 0x2F;
    _0040EBCC[0xFD] = 0x05;
    _0040E7CC[0xFE] = 0x19;
    _0040EBCC[0xFE] = 0x05;
    _0040E7CC[0xFF] = 0x0B;
    _0040EBCC[0xFF] = 0x00;

    strcpy(_0040E574[0x00], _0040E010[0]);
    strcpy(_0040E574[0x01], _0040E010[1]);
    strcpy(_0040E574[0x02], _0040E010[2]);
    strcpy(_0040E574[0x03], _0040E010[3]);
    strcpy(_0040E574[0x04], _0040E010[4]);
    strcpy(_0040E574[0x05], _0040E010[5]);
    strcpy(_0040E574[0x06], _0040E010[6]);
    strcpy(_0040E574[0x07], _0040E010[7]);
    strcpy(_0040E574[0x08], _0040E010[8]);
    strcpy(_0040E574[0x09], _0040E010[9]);
    strcpy(_0040E574[0x0A], _0040E010[10]);
    strcpy(_0040E574[0x0B], _0040E010[11]);
    strcpy(_0040E574[0x0C], _0040E010[12]);
    strcpy(_0040E574[0x0D], _0040E010[13]);
    strcpy(_0040E574[0x0E], _0040E010[14]);
    strcpy(_0040E574[0x0F], _0040E010[15]);
    strcpy(_0040E574[0x10], _0040E010[16]);
    strcpy(_0040E574[0x11], _0040E010[17]);
    strcpy(_0040E574[0x02], _0040E010[18]);
    strcpy(_0040E574[0x12], _0040E010[19]);
    strcpy(_0040E574[0x13], _0040E010[20]);
    strcpy(_0040E574[0x14], _0040E010[21]);
    strcpy(_0040E574[0x15], _0040E010[22]);
    strcpy(_0040E574[0x16], _0040E010[23]);
    strcpy(_0040E574[0x17], _0040E010[24]);
    strcpy(_0040E574[0x18], _0040E010[25]);
    strcpy(_0040E574[0x19], _0040E010[26]);
    strcpy(_0040E574[0x1A], _0040E010[27]);
    strcpy(_0040E574[0x1B], _0040E010[28]);
    strcpy(_0040E574[0x1C], _0040E010[29]);
    strcpy(_0040E574[0x1D], _0040E010[30]);
    strcpy(_0040E574[0x1E], _0040E010[31]);
    strcpy(_0040E574[0x1F], _0040E010[32]);
    strcpy(_0040E574[0x20], _0040E010[33]);
    strcpy(_0040E574[0x21], _0040E010[34]);
    strcpy(_0040E574[0x22], _0040E010[35]);
    strcpy(_0040E574[0x23], _0040E010[36]);
    strcpy(_0040E574[0x24], _0040E010[37]);
    strcpy(_0040E574[0x25], _0040E010[38]);
    strcpy(_0040E574[0x26], _0040E010[39]);
    strcpy(_0040E574[0x27], _0040E010[40]);
    strcpy(_0040E574[0x28], _0040E010[41]);
    strcpy(_0040E574[0x29], _0040E010[42]);
    strcpy(_0040E574[0x2A], _0040E010[43]);
    strcpy(_0040E574[0x2B], _0040E010[44]);
    strcpy(_0040E574[0x2C], _0040E010[45]);
    strcpy(_0040E574[0x2D], _0040E010[46]);
    strcpy(_0040E574[0x2E], _0040E010[47]);
    strcpy(_0040E574[0x2F], _0040E010[48]);
    strcpy(_0040E574[0x30], _0040E010[49]);
    strcpy(_0040E574[0x31], _0040E010[50]);
    strcpy(_0040E574[0x32], _0040E010[51]);
    strcpy(_0040E574[0x33], _0040E010[52]);
    strcpy(_0040E574[0x34], _0040E010[53]);
    strcpy(_0040E574[0x35], _0040E010[54]);
    strcpy(_0040E574[0x36], _0040E010[55]);
    strcpy(_0040E574[0x37], _0040E010[56]);
    strcpy(_0040E574[0x38], _0040E010[57]);
    strcpy(_0040E574[0x39], _0040E010[58]);
    strcpy(_0040E574[0x3A], _0040E010[59]);
    strcpy(_0040E574[0x3B], _0040E010[60]);
}

// done
void _00402C3F()
{
    // VOID
}

// done
void DBG_Disassembly(UINT32 *v1, CHAR* v2, UINT32 v3, UINT32 *v4)
{
    CHAR ebp_C[12];
    UINT32 ebp_10;
    CHAR ebp_1C[12];
    UINT32 ebp_20;
    UINT32 ebp_24;
    CHAR ebp_30[12];
    UINT32 ebp_34;
    UINT32 ebp_38 = *v1;
    UINT32 ebp_3C;
    CHAR ebp_48[12];
    CHAR ebp_54[12];
    UINT32 ebp_58;
	ebp_24 = 8;

    if (v3 == 0)
    {
        *v1 = _004058E7(*v1);
        ebp_24 = 4;
    }
    ebp_20 = *v1;
    if (v4)
    {
        ebp_34 = *v4;
    }
    else
    {
        ebp_34 = _00410C50[*v1 >> 0x13][*v1 & 0x7FFFF];
    }
    *v1 += 1;
    sprintf(ebp_30, "%02X", ebp_34);
    if (v3 == 1)
    {
        sprintf(ebp_48, "%p", ebp_38);
    }
    else
    {
        sprintf(ebp_48, "%04X", ebp_38);
    }
    switch (_0040D2B4[_0040EBCC[ebp_34]])
    {
	case 0:
        sprintf(v2, _0040D14C[_0040EBCC[ebp_34]], ebp_48, ebp_30, _0040E574[_0040E7CC[ebp_34]]);
		break;
    case 1:
        ebp_10 = _00410C50[*v1 >> 0x13][*v1 & 0x7FFFF];
        *v1 += 1;
        if (_0040EBCC[ebp_34] == 3)
        {
            if (v3 == 1)
            {
                ebp_3C = *v1+ebp_10;
            }
            else
            {
                ebp_3C = *v1 - ebp_20 + ebp_38 + ebp_10;
            }
            if (ebp_10 & 0x80)
            {
                ebp_3C -= 0x100;
            }
            ebp_58 = ebp_3C&0xFF;
            sprintf(ebp_54, "%02X", ebp_58);
            ebp_3C >>= 8;
            sprintf(ebp_C, "%02X", ebp_3C);
            sprintf(ebp_1C, "%02X", ebp_10);
            sprintf(v2, _0040D14C[_0040EBCC[ebp_34]], ebp_48, ebp_30, ebp_1C, _0040E574[_0040E7CC[ebp_34]], ebp_C, ebp_54);
        }
        else
        {
            sprintf(ebp_54, "%02X", ebp_10);
            sprintf(v2, _0040D14C[_0040EBCC[ebp_34]], ebp_48, ebp_30, ebp_54, _0040E574[_0040E7CC[ebp_34]], ebp_54);
        }
		break;
    case 2:
        ebp_58 = _00410C50[*v1 >> 0x13][*v1 & 0x7FFFF];
        *v1 += 1;
        sprintf(ebp_54, "%02X", ebp_58);
        ebp_3C = _00410C50[*v1 >> 0x13][*v1 & 0x7FFFF];
        *v1 += 1;
        sprintf(ebp_C, "%02X", ebp_3C);
        sprintf(v2, _0040D14C[_0040EBCC[ebp_34]], ebp_48, ebp_30, ebp_54, ebp_C, _0040E574[_0040E7CC[ebp_34]], ebp_C, ebp_54);
		break;
    }
    if (v3 == 0)
    {
        *v1 = *v1 - ebp_20 + ebp_38;
    }
}

// done
UINT32 _00402FE9(UINT32 v1)
{
    return _0040D2B4[_0040EBCC[_00410C50[v1 >> 0x13][v1 & 0x7FFFF]]];
}

// done
BOOL _00403020()
{
    memset(_0040EFCC, 0, sizeof(_0040EFCC));
    memset(_0040F1CC, 0, sizeof(_0040F1CC));
    memset(FileMappingList, 0, sizeof(FileMappingList));
    FileMappingQuantity = 0;
    return TRUE;
}

// done
UINT8* _00403070(LPCSTR lpFileName, UINT32 writable)
{
    UINT32 ebp_10 = FileMappingQuantity;
    UINT32 dwDesiredAccess = GENERIC_READ;
    if (writable)
    {
        dwDesiredAccess |= GENERIC_WRITE;
    }
    _0040EFCC[ebp_10] = CreateFile(lpFileName, dwDesiredAccess, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (_0040EFCC[ebp_10] == INVALID_HANDLE_VALUE)
    {
        MessageBox(NULL, lpFileName, "打开文件失败", MB_OK);
        return NULL;
    }
    UINT32 flProtect = writable ? PAGE_READWRITE : PAGE_READONLY;
    _0040F1CC[ebp_10] = CreateFileMapping(_0040EFCC[ebp_10], NULL, flProtect, 0, 0, NULL);
    if (_0040F1CC[ebp_10] != NULL && GetLastError() == ERROR_ALREADY_EXISTS)
    {
        CloseHandle(_0040F1CC[ebp_10]);
		_0040F1CC[ebp_10] = NULL;
        MessageBox(NULL, lpFileName, "文件已经被映射", MB_OK);
    }
    if (_0040F1CC[ebp_10] == NULL)
    {
        CloseHandle(_0040EFCC[ebp_10]);
        _0040EFCC[ebp_10] = NULL;
        MessageBox(NULL, lpFileName, "创建映射失败", MB_OK);
        return NULL;
    }
    UINT32 ebp_8 = writable ? FILE_MAP_WRITE : FILE_MAP_READ;
    FileMappingList[ebp_10] = (UINT8*)MapViewOfFile(_0040F1CC[ebp_10], ebp_8, 0, 0, 0);
    if (FileMappingList[ebp_10] == NULL)
    {
        MessageBox(NULL, lpFileName, "映射文件失败", MB_OK);
        CloseHandle(_0040F1CC[ebp_10]);
        CloseHandle(_0040EFCC[ebp_10]);
        _0040F1CC[ebp_10] = NULL;
        _0040EFCC[ebp_10] = NULL;
        return NULL;
    }
    FileMappingQuantity += 1;
    return FileMappingList[ebp_10];
}

// done
BOOL _00403260()
{
    for (UINT32 ebp_4 = 0; ebp_4 < FileMappingQuantity; ebp_4++)
    {
        UnmapViewOfFile(FileMappingList[ebp_4]);
        CloseHandle(_0040F1CC[ebp_4]);
        CloseHandle(_0040EFCC[ebp_4]);
    }
    FileMappingQuantity = 0;
    return TRUE;
}

// 按键响应
void _004032D0(UINT32 v1)
{
    SleepFlag = 0;
    bWantInt = 1;
    pRam[0x24E] = _0040F5D0[v1] | 0x80; // 保存按键信息到_KEYCODE
    *(UINT32 *)(pRam+0x04) |= 0x80; // 标记中断位
}

// done
BOOL _00403317()
{
    memset(_0040F5D0, 0x2D, 0x100); // VK_INSERT
	// 电脑按键映射到词典按键
    _0040F5D0[0x08] = 0x37; // VK_BACK
    _0040F5D0[0x09] = 0x2B; // VK_TAB
    _0040F5D0[0x0D] = 0x2F; // VK_RETURN
    _0040F5D0[0x10] = 0x28; // VK_SHIFT
    _0040F5D0[0x11] = 0x28; // VK_CONTROL
    _0040F5D0[0x12] = 0x01; // VK_MENU
    _0040F5D0[0x14] = 0x20; // VK_CAPITAL
    _0040F5D0[0x1B] = 0x2E; // VK_ESCAPE
    _0040F5D0[0x20] = 0x36; // VK_SPACE
    _0040F5D0[0x21] = 0x3A; // VK_PRIOR
    _0040F5D0[0x22] = 0x3B; // VK_NEXT
    _0040F5D0[0x24] = 0x2A; // VK_HOME
    _0040F5D0[0x25] = 0x37; // VK_LEFT
    _0040F5D0[0x26] = 0x35; // VK_UP
    _0040F5D0[0x27] = 0x39; // VK_RIGHT
    _0040F5D0[0x28] = 0x38; // VK_DOWN
    _0040F5D0[0x2D] = 0x29; // VK_INSERT
    _0040F5D0[0x2E] = 0x2C; // VK_DELETE
    _0040F5D0[0x30] = 0x31; // VK_0
    _0040F5D0[0x31] = 0x08; // VK_1
    _0040F5D0[0x32] = 0x09; // VK_2
    _0040F5D0[0x33] = 0x0A; // VK_3
    _0040F5D0[0x34] = 0x0B; // VK_4
    _0040F5D0[0x35] = 0x0C; // VK_5
    _0040F5D0[0x36] = 0x0D; // VK_6
    _0040F5D0[0x37] = 0x0E; // VK_7
    _0040F5D0[0x38] = 0x0F; // VK_8
    _0040F5D0[0x39] = 0x30; // VK_9
    _0040F5D0[0x41] = 0x18; // VK_A
    _0040F5D0[0x42] = 0x25; // VK_B
    _0040F5D0[0x43] = 0x23; // VK_C
    _0040F5D0[0x44] = 0x1A; // VK_D
    _0040F5D0[0x45] = 0x12; // VK_E
    _0040F5D0[0x46] = 0x1B; // VK_F
    _0040F5D0[0x47] = 0x1C; // VK_G
    _0040F5D0[0x48] = 0x1D; // VK_H
    _0040F5D0[0x49] = 0x17; // VK_I
    _0040F5D0[0x4A] = 0x1E; // VK_J
    _0040F5D0[0x4B] = 0x1F; // VK_K
    _0040F5D0[0x4C] = 0x34; // VK_L
    _0040F5D0[0x4D] = 0x27; // VK_M
    _0040F5D0[0x4E] = 0x26; // VK_N
    _0040F5D0[0x4F] = 0x32; // VK_O
    _0040F5D0[0x50] = 0x33; // VK_P
    _0040F5D0[0x51] = 0x10; // VK_Q
    _0040F5D0[0x52] = 0x13; // VK_R
    _0040F5D0[0x53] = 0x19; // VK_S
    _0040F5D0[0x54] = 0x14; // VK_T
    _0040F5D0[0x55] = 0x16; // VK_U
    _0040F5D0[0x56] = 0x24; // VK_V
    _0040F5D0[0x57] = 0x11; // VK_W
    _0040F5D0[0x58] = 0x22; // VK_X
    _0040F5D0[0x59] = 0x15; // VK_Y
    _0040F5D0[0x5A] = 0x21; // VK_Z
    _0040F5D0[0x60] = 0x31; // VK_NUMPAD0
    _0040F5D0[0x61] = 0x08; // VK_NUMPAD1
    _0040F5D0[0x62] = 0x09; // VK_NUMPAD2
    _0040F5D0[0x63] = 0x0A; // VK_NUMPAD3
    _0040F5D0[0x64] = 0x0B; // VK_NUMPAD4
    _0040F5D0[0x65] = 0x0C; // VK_NUMPAD5
    _0040F5D0[0x66] = 0x0D; // VK_NUMPAD6
    _0040F5D0[0x67] = 0x0E; // VK_NUMPAD7
    _0040F5D0[0x68] = 0x0F; // VK_NUMPAD8
    _0040F5D0[0x69] = 0x30; // VK_NUMPAD9
    _0040F5D0[0x6A] = 0x07; // VK_MULTIPLY
    _0040F5D0[0x6B] = 0x06; // VK_ADD
    _0040F5D0[0x6C] = 0x05; // VK_SEPARATOR
    _0040F5D0[0x6D] = 0x04; // VK_SUBTRACT
    _0040F5D0[0x6E] = 0x02; // VK_DECIMAL
    _0040F5D0[0x6F] = 0x03; // VK_DIVIDE
    _0040F5D0[0x70] = 0x2D; // VK_F1
    _0040F5D0[0x91] = 0x00; // VK_SCROLL
    return TRUE;
}

// done
BOOL InitLcd()
{
	bool ebp_1C;
	__try {
		hbmLcd = CreateBitmap(160, 96, 1, 1, NULL);
		ebp_1C = hbmLcd == NULL;
		if (ebp_1C)
		{
			__leave;
		}
		hdcLcd = CreateCompatibleDC(NULL);
		ebp_1C = hdcLcd == NULL;
		if (ebp_1C)
		{
			__leave;
		}
		hbmScreen = CreateBitmap(400, 192, 1, 1, NULL);
		ebp_1C = hbmScreen == NULL;
		if (ebp_1C)
		{
			__leave;
		}
		hdcScreen = CreateCompatibleDC(NULL);
		ebp_1C = hdcScreen == NULL;
		if (ebp_1C)
		{
			__leave;
		}
		hbmResource = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP));
		ebp_1C = hbmResource == NULL;
		if (ebp_1C)
		{
			__leave;
		}
		hdcResource = CreateCompatibleDC(NULL);
		ebp_1C = hdcResource == NULL;
	}
	__finally
	{
		if (ebp_1C)
		{
			if (hbmLcd)
			{
				DeleteObject(hbmLcd);
			}
			if (hdcLcd)
			{
				DeleteDC(hdcLcd);
			}
			if (hbmScreen)
			{
				DeleteObject(hbmScreen);
			}
			if (hdcScreen)
			{
				DeleteDC(hdcScreen);
			}
			if (hbmResource)
			{
				DeleteObject(hbmResource);
			}
			if (hdcResource)
			{
				DeleteDC(hdcResource);
			}
		}
		else
		{
			SelectObject(hdcLcd, hbmLcd);
			SelectObject(hdcResource, hbmResource);
			SelectObject(hdcScreen, hbmScreen);
		}
	}
    _00403B7C();
    return !ebp_1C;
}

// done
BOOL DeleteLcd()
{
    if (hdcLcd)
    {
        DeleteDC(hdcLcd);
    }
    if (hbmLcd)
    {
        DeleteObject(hbmLcd);
    }
    if (hdcScreen)
    {
        DeleteDC(hdcScreen);
    }
    if (hbmScreen)
    {
        DeleteObject(hbmScreen);
    }
    if (hdcResource)
    {
        DeleteDC(hdcResource);
    }
    if (hbmResource)
    {
        DeleteObject(hbmResource);
    }
    return TRUE;
}

// 设置屏幕背景色
void _00403802(UINT8 v1)
{
	v1 = 0x3F - v1;
	v1 <<= 2;
	COLORREF ebp_4 = RGB(v1, v1, v1);
	SetBkColor(hDC, ebp_4);
}

// 屏幕绘制
void _0040385D()
{
    int ebp_4;
    int ebp_8;
    pVideoMemory = pRam + 0x400;
    for (ebp_8 = 0; ebp_8 < 0x42; ebp_8++)
    {
        for (ebp_4 = 0; ebp_4 < 0x13; ebp_4++)
        {
            pvBitsLcd[(0x41 - ebp_8) * 20 + ebp_4+1] = ~pVideoMemory[(ebp_8 << 5) + ebp_4];
        }
    }
    for (ebp_8 = 0x42; ebp_8 < 0x60; ebp_8++)
    {
        for (ebp_4 = 0; ebp_4 < 0x13; ebp_4++)
        {
            pvBitsLcd[ebp_8 * 20 + ebp_4+1] = ~pVideoMemory[(ebp_8 << 5) + ebp_4];
        }
    }
    for (ebp_8 = 0; ebp_8 < 0x41; ebp_8++)
    {
        pvBitsLcd[(0x40 - ebp_8) * 20] = ~pVideoMemory[(ebp_8 << 5) + 19];
    }
    for (ebp_8 = 0x41; ebp_8 < 0x5F; ebp_8++)
    {
        pvBitsLcd[(ebp_8+1) * 20] = ~pVideoMemory[(ebp_8 << 5) + 19];
    }
    pvBitsLcd[0x514] = ~pVideoMemory[0xBF3];
    pvBitsLcd[0x515] = ~pVideoMemory[0xC00];
    SetBitmapBits(hbmLcd, 1920, pvBitsLcd);
    FillRect(hdcScreen, &_0040FD30, (HBRUSH)GetStockObject(WHITE_BRUSH));
    FillRect(hdcScreen, &_00410340, (HBRUSH)GetStockObject(WHITE_BRUSH));
    StretchBlt(hdcScreen, 41, 0, 318, 192, hdcLcd, 0, 0, 159, 96, SRCCOPY);
	// 判断是否显示屏幕左右的图标
    for (ebp_8 = 0; ebp_8 < 0x60; ebp_8++)
    {
        if ((pvBitsLcd[ebp_8*20+19]&0x01) == 0x00)
        {
			BitBlt(hdcScreen, _0040F6D0[_0040FCD0[ebp_8]].left - 108,
				_0040F6D0[_0040FCD0[ebp_8]].top - 108,
				_0040F6D0[_0040FCD0[ebp_8]].right - _0040F6D0[_0040FCD0[ebp_8]].left,
				_0040F6D0[_0040FCD0[ebp_8]].bottom - _0040F6D0[_0040FCD0[ebp_8]].top,
				hdcResource, _0040FD40[_0040FCD0[ebp_8]].left, _0040FD40[_0040FCD0[ebp_8]].top, SRCCOPY);
        }
    }
    BitBlt(hDC, 0, 0, 400, 192, hdcScreen, 0, 0, SRCCOPY);
}

// done
void _00403B7C()
{
	int ebp_4;
    SetRect(&_0040FD30, 0, 0, 41, 192);
    SetRect(&_00410340, 359, 0, 400, 192);
    for (ebp_4 = 0; ebp_4 < 4; ebp_4++)
    {
        SetRect(_0040FD40 + (ebp_4 * 8    ), 1, 0, 5, 1); // 数字上横
        SetRect(_0040FD40 + (ebp_4 * 8 + 1), 0, 1, 1, 5); // 数字左上竖
        SetRect(_0040FD40 + (ebp_4 * 8 + 2), 5, 1, 6, 5); // 数字右上竖
        SetRect(_0040FD40 + (ebp_4 * 8 + 3), 1, 5, 5, 6); // 数字中横
        SetRect(_0040FD40 + (ebp_4 * 8 + 4), 0, 6, 1, 10); // 数字左下竖
        SetRect(_0040FD40 + (ebp_4 * 8 + 5), 5, 6, 6, 10); // 数字右下竖
        SetRect(_0040FD40 + (ebp_4 * 8 + 6), 1, 10, 5, 11); // 数字下横
        SetRect(_0040FD40 + (ebp_4 * 8 + 7), 7, 10, 8, 11); // 小数点
    }
    SetRect(&_0040FD40[0x20], 0, 12, 7, 16); // 上
    for (ebp_4 = 0; ebp_4 < 0x26; ebp_4++)
    {
        SetRect(&_0040FD40[ebp_4+0x21], 0, 18, 7, 20); // 横线
    }
    SetRect(&_0040FD40[0x47], 0, 22, 7, 26); // 下
    for (ebp_4 = 0; ebp_4 < 8; ebp_4++)
    {
        SetRect(&_0040FD40[ebp_4+0x48], 36, 0, 51, 9); // 功能指示
    }
    SetRect(&_0040FD40[0x50], 9, 10, 34, 22); // NUM
    SetRect(&_0040FD40[0x51], 9, 22, 34, 34); // CAPS
    //
    SetRect(&_0040FD40[0x53], 9, 34, 34, 46); // SHIFT
    SetRect(&_0040FD40[0x54], 36, 36, 64, 46); // 闹铃
    SetRect(&_0040FD40[0x55], 54, 18, 71, 33); // 发音
    SetRect(&_0040FD40[0x56], 54, 0, 70, 16); // 闹钟开关
    SetRect(&_0040FD40[0x57], 0, 28, 7, 36); // 上翻页
    SetRect(&_0040FD40[0x58], 0, 38, 7, 46); // 下翻页
    SetRect(&_0040FD40[0x59], 36, 22, 51, 33); // 左
    SetRect(&_0040FD40[0x5A], 36, 10, 51, 21); // 右
    SetRect(&_0040FD40[0x5B], 9, 0, 28, 8); // 电池电量
    SetRect(&_0040FD40[0x5C], 9, 0, 28, 8); // 电池电量
    SetRect(&_0040FD40[0x5D], 9, 0, 28, 8); // 电池电量
													//	x	y	w	h
    SetRect(&_0040F6D0[0x00], 112, 119, 116, 120);	//	4	11	4	1	(千位)数字上横
    SetRect(&_0040F6D0[0x01], 111, 120, 112, 124);	//	3	12	1	4	(千位)数字左上竖
    SetRect(&_0040F6D0[0x02], 116, 120, 117, 124);	//	8	12	1	4	(千位)数字右上竖
    SetRect(&_0040F6D0[0x03], 112, 124, 116, 125);	//	4	16	4	1	(千位)数字中横
    SetRect(&_0040F6D0[0x04], 111, 125, 112, 129);	//	3	17	1	4	(千位)数字左下竖
    SetRect(&_0040F6D0[0x05], 116, 125, 117, 129);	//	8	17	1	4	(千位)数字右下竖
    SetRect(&_0040F6D0[0x06], 112, 129, 116, 130);	//	4	21	4	1	(千位)数字下横
    SetRect(&_0040F6D0[0x07], 118, 129, 119, 130);	//	10	21	1	1	小数点
    SetRect(&_0040F6D0[0x08], 121, 119, 125, 120);	//	13	11	4	1	(百位)数字上横
    SetRect(&_0040F6D0[0x09], 120, 120, 121, 124);	//	12	12	1	4	(百位)数字左上竖
    SetRect(&_0040F6D0[0x0A], 125, 120, 126, 124);	//	17	12	1	4	(百位)数字右上竖
    SetRect(&_0040F6D0[0x0B], 121, 124, 125, 125);	//	13	16	4	1	(百位)数字中横
    SetRect(&_0040F6D0[0x0C], 120, 125, 121, 129);	//	12	17	1	4	(百位)数字左下竖
    SetRect(&_0040F6D0[0x0D], 125, 125, 126, 129);	//	17	17	1	4	(百位)数字右下竖
    SetRect(&_0040F6D0[0x0E], 121, 129, 125, 130);	//	13	21	4	1	(百位)数字下横
    SetRect(&_0040F6D0[0x0F], 127, 129, 128, 130);	//	19	21	1	1	小数点
    SetRect(&_0040F6D0[0x10], 131, 119, 135, 120);	//	23	11	4	1	(十位)数字上横
    SetRect(&_0040F6D0[0x11], 130, 120, 135, 124);	//	22	12	5	4	(十位)数字左上竖
    SetRect(&_0040F6D0[0x12], 135, 120, 136, 124);	//	27	12	1	4	(十位)数字右上竖
    SetRect(&_0040F6D0[0x13], 131, 124, 135, 125);	//	23	16	4	1	(十位)数字中横
    SetRect(&_0040F6D0[0x14], 130, 125, 131, 129);	//	22	17	1	4	(十位)数字左下竖
    SetRect(&_0040F6D0[0x15], 135, 125, 136, 129);	//	27	17	1	3	(十位)数字右下竖
    SetRect(&_0040F6D0[0x16], 131, 129, 135, 130);	//	23	21	4	1	(十位)数字下横
    SetRect(&_0040F6D0[0x17], 137, 129, 138, 130);	//	29	21	1	1	小数点
    SetRect(&_0040F6D0[0x18], 140, 119, 144, 120);	//	32	11	4	1	(个位)数字上横
    SetRect(&_0040F6D0[0x19], 139, 120, 140, 124);	//	31	12	1	4	(个位)数字左上竖
    SetRect(&_0040F6D0[0x1A], 144, 120, 145, 124);	//	36	12	1	4	(个位)数字右上竖
    SetRect(&_0040F6D0[0x1B], 140, 124, 144, 125);	//	32	16	4	1	(个位)数字中横
    SetRect(&_0040F6D0[0x1C], 139, 125, 140, 129);	//	31	17	1	4	(个位)数字左下竖
    SetRect(&_0040F6D0[0x1D], 144, 125, 145, 129);	//	36	17	1	4	(个位)数字右下竖
    SetRect(&_0040F6D0[0x1E], 140, 129, 144, 130);	//	32	21	4	1	(个位)数字下横
    SetRect(&_0040F6D0[0x1F], 127, 122, 129, 127);	//	19	14	2	5	小数点 todo数据中间的冒号
    SetRect(&_0040F6D0[0x20], 110, 137, 117, 141);	//	2	29	7	4	上
    for (ebp_4 = 0; ebp_4 < 0x26; ebp_4++)	
    {
        SetRect(&_0040F6D0[ebp_4+0x21], 110, ebp_4*4+143, 117, ebp_4 * 4 + 145); //	2	35+4a	7	2 横线
    }
    SetRect(&_0040F6D0[0x47], 110, 295, 117, 299);	//	2	187	7	4	下
    for (ebp_4 = 0; ebp_4 < 8; ebp_4++)
    {
        SetRect(&_0040F6D0[ebp_4+0x48], 481, ebp_4 * 23+ 113, 495, ebp_4 * 23 + 122);	//	373	5+23a	14	9	功能指示：释义、例句、例证、习语、复合、派生、用法、同反
    }
    SetRect(&_0040F6D0[0x50], 121, 144, 146, 156);	//	13	36	25	12	NUM
    SetRect(&_0040F6D0[0x51], 121, 164, 146, 176);	//	13	56	25	12	CAPS
    SetRect(&_0040F6D0[0x52], 121, 144, 146, 156);	//	13	36	25	12	
    SetRect(&_0040F6D0[0x53], 121, 184, 146, 196);	//	13	76	25	12	SHIFT
    SetRect(&_0040F6D0[0x54], 119, 203, 147, 213);	//	11	95	28	10	闹铃
    SetRect(&_0040F6D0[0x55], 126, 217, 143, 232);	//	18	109	17	15	发音
    SetRect(&_0040F6D0[0x56], 126, 233, 142, 249);	//	18	125	16	16	闹钟开关
    SetRect(&_0040F6D0[0x57], 130, 252, 137, 260);	//	22	144	7	8	上翻页
    SetRect(&_0040F6D0[0x58], 130, 263, 137, 271);	//	22	155	7	8	下翻页
    SetRect(&_0040F6D0[0x59], 126, 288, 141, 299);	//	18	180	15	11	左
    SetRect(&_0040F6D0[0x5A], 481, 288, 496, 299);	//	373	180	15	11	右
    SetRect(&_0040F6D0[0x5B], 124, 278, 143, 286);	//	16	170	19	8	电池电量
    SetRect(&_0040F6D0[0x5C], 124, 278, 143, 286);	//	16	170	19	8	电池电量
    SetRect(&_0040F6D0[0x5D], 124, 278, 143, 286);	//	16	170	19	8	电池电量

    _0040FCD0[0x00] = 0x0B; // (百位)数字中横
    _0040FCD0[0x01] = 0x09; // (百位)数字左上竖
    _0040FCD0[0x02] = 0x08; // (百位)数字上横
    _0040FCD0[0x03] = 0x0A; // (百位)数字右上竖
    _0040FCD0[0x04] = 0x1F; // 小数点
    _0040FCD0[0x05] = 0x11; // (十位)数字左上竖
    _0040FCD0[0x06] = 0x10; // (十位)数字上横
    _0040FCD0[0x07] = 0x12; // (十位)数字右上竖
    _0040FCD0[0x08] = 0x13; // (十位)数字中横
    _0040FCD0[0x09] = 0x19; // (个位)数字左上竖
    _0040FCD0[0x0A] = 0x18; // (个位)数字上横
    _0040FCD0[0x0B] = 0x1A; // (个位)数字右上竖
    _0040FCD0[0x0C] = 0x1B; // (个位)数字中横
    _0040FCD0[0x0D] = 0x1D; // (个位)数字右下竖
    _0040FCD0[0x0E] = 0x1E; // (个位)数字下横
    _0040FCD0[0x0F] = 0x1C; // (个位)数字左下竖
    _0040FCD0[0x10] = 0x17; // 小数点
    _0040FCD0[0x11] = 0x15; // (十位)数字右下竖
    _0040FCD0[0x12] = 0x16; // (十位)数字下横
    _0040FCD0[0x13] = 0x14; // (十位)数字左下竖
    _0040FCD0[0x14] = 0x0F; // 小数点
    _0040FCD0[0x15] = 0x48; // 功能指示
    _0040FCD0[0x16] = 0x0D; // (百位)数字右下竖
    _0040FCD0[0x17] = 0x0E; // (百位)数字下横
    _0040FCD0[0x18] = 0x50; // NUM
    _0040FCD0[0x19] = 0x0C; // (百位)数字左下竖
    _0040FCD0[0x1A] = 0x09; // (百位)数字左上竖
    _0040FCD0[0x1B] = 0x20; // 上
    _0040FCD0[0x1C] = 0x05; // (千位)数字右下竖
    _0040FCD0[0x1D] = 0x21; // 横线
    _0040FCD0[0x1E] = 0x06; // (千位)数字下横
    _0040FCD0[0x1F] = 0x49; // 功能指示
    _0040FCD0[0x20] = 0x22; // 横线
    _0040FCD0[0x21] = 0x04; // (千位)数字左下竖
    _0040FCD0[0x22] = 0x51; // CAPS
    _0040FCD0[0x23] = 0x23; // 横线
    _0040FCD0[0x24] = 0x4A; // 功能指示
    _0040FCD0[0x25] = 0x03; // (千位)数字中横
    _0040FCD0[0x26] = 0x24; // 横线
    _0040FCD0[0x27] = 0x01; // (千位)数字左上竖
    _0040FCD0[0x28] = 0x25; // 横线
    _0040FCD0[0x29] = 0x26; // 横线
    _0040FCD0[0x2A] = 0x4B; // 功能指示
    _0040FCD0[0x2B] = 0x27; // 横线
    _0040FCD0[0x2C] = 0x28; // 横线
    _0040FCD0[0x2D] = 0x53; // SHIFT
    _0040FCD0[0x2E] = 0x00; // (千位)数字上横
    _0040FCD0[0x2F] = 0x29; // 横线
    _0040FCD0[0x30] = 0x02; // (千位)数字右上竖
    _0040FCD0[0x31] = 0x4C; // 功能指示
    _0040FCD0[0x32] = 0x2A; // 横线
    _0040FCD0[0x33] = 0x2B; // 横线
    _0040FCD0[0x34] = 0x54; // 闹铃
    _0040FCD0[0x35] = 0x2C; // 横线
    _0040FCD0[0x36] = 0x2D; // 横线
    _0040FCD0[0x37] = 0x2E; // 横线
    _0040FCD0[0x38] = 0x2F; // 横线
    _0040FCD0[0x39] = 0x00; // (千位)数字上横
    _0040FCD0[0x3A] = 0x00; // (千位)数字上横
    _0040FCD0[0x3B] = 0x55; // 发音
    _0040FCD0[0x3C] = 0x30; // 横线
    _0040FCD0[0x3D] = 0x31; // 横线
    _0040FCD0[0x3E] = 0x32; // 横线
    _0040FCD0[0x3F] = 0x33; // 横线
    _0040FCD0[0x40] = 0x34; // 横线
    _0040FCD0[0x41] = 0x4D; // 功能指示
    _0040FCD0[0x42] = 0x35; // 横线
    _0040FCD0[0x43] = 0x36; // 横线
    _0040FCD0[0x44] = 0x56; // 闹钟开关
    _0040FCD0[0x45] = 0x37; // 横线
    _0040FCD0[0x46] = 0x38; // 横线
    _0040FCD0[0x47] = 0x39; // 横线
    _0040FCD0[0x48] = 0x3A; // 横线
    _0040FCD0[0x49] = 0x3B; // 横线
    _0040FCD0[0x4A] = 0x3C; // 横线
    _0040FCD0[0x4B] = 0x3D; // 横线
    _0040FCD0[0x4C] = 0x57; // 上翻页
    _0040FCD0[0x4D] = 0x3E; // 横线
    _0040FCD0[0x4E] = 0x3F; // 横线
    _0040FCD0[0x4F] = 0x3F; // 横线
    _0040FCD0[0x50] = 0x40; // 横线
    _0040FCD0[0x51] = 0x41; // 横线
    _0040FCD0[0x52] = 0x58; // 下翻页
    _0040FCD0[0x53] = 0x42; // 横线
    _0040FCD0[0x54] = 0x43; // 横线
    _0040FCD0[0x55] = 0x44; // 横线
    _0040FCD0[0x56] = 0x45; // 横线
    _0040FCD0[0x57] = 0x46; // 横线
    _0040FCD0[0x58] = 0x47; // 下
    _0040FCD0[0x59] = 0x5B; // 电池电量
    _0040FCD0[0x5A] = 0x5C; // 电池电量
    _0040FCD0[0x5B] = 0x5D; // 电池电量
    _0040FCD0[0x5C] = 0x4E; // 功能指示
    _0040FCD0[0x5D] = 0x59; // 左
    _0040FCD0[0x5E] = 0x4F; // 功能指示
    _0040FCD0[0x5F] = 0x5A; // 右
}

// done
// _00404670
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
    hInst = hInstance;
    if (!EMU_Init(0))
    {
		return 0;
	}
    EMU_MessageLoop();
    EMU_Destroy();

    return 0;
}

// done
BOOL EMU_Init(UINT32 ebp_8)
{
    _0040BA15();
    if (AllocMemory() == NULL)
    {
        MessageBox(NULL, "Alloc memory failure!", NULL, MB_OK);
        return FALSE;
    }
    if (LoadRom() == NULL)
    {
        _00405558();
        MessageBox(NULL, "Load ROM failure!", NULL, MB_OK);
        return FALSE;
    }
    if (InitLcd() == NULL)
    {
        MessageBox(NULL, "Init LCD failure!", NULL, MB_OK);
        return FALSE;
    }
    _0040100A();
    _00403317();
    _004013F0();
    _004047B6();
    hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    return TRUE;
}

// done
HANDLE EMU_GetACKHandle()
{
    return hEvent;
}

// done
HWND EMU_GetMainWnd()
{
    return hWnd;
}

// done
BOOL EMU_Destroy()
{
    CloseHandle(hEvent);
    _00404781();
    _00405558();
    DeleteLcd();
    _00402C3F();
    return TRUE;
}

// done
void _00404781()
{
    ReleaseDC(hWnd, hDC);
    KillTimer(hWnd, 1);
    KillTimer(hWnd, 2);
}

// done
void _004047B6()
{
    WNDCLASSEX wcex;
    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = WndProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInst;
    wcex.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(102));
    wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
    wcex.lpszMenuName = NULL;
    wcex.lpszClassName = szTitle;
    wcex.hIconSm = NULL;
    RegisterClassEx(&wcex);

    int ebp_4 = GetSystemMetrics(SM_CXDLGFRAME)*2+SCREEN_WIDTH;
    int ebp_8 = GetSystemMetrics(SM_CYDLGFRAME)*2+ GetSystemMetrics(SM_CYCAPTION)+SCREEN_HEIGHT;
    hWnd = CreateWindowEx(WS_EX_ACCEPTFILES, szTitle, szTitle,
        WS_OVERLAPPED | WS_MINIMIZEBOX | WS_SYSMENU | WS_CAPTION,
        (GetSystemMetrics(SM_CXSCREEN) - ebp_4) / 2,
        (GetSystemMetrics(SM_CYSCREEN) - ebp_8) / 2,
        ebp_4, ebp_8, NULL, NULL, hInst, NULL);
    ShowWindow(hWnd, SW_SHOW);
    UpdateWindow(hWnd);
    GetWindowRect(hWnd, &_00410B10);
    hDC = GetDC(hWnd);
    SetBkColor(hDC, RGB(0x54, 0x5D, 0x5C)); // 0x5C5D54
    SetTimer(hWnd, 1, 100, NULL);
    SetTimer(hWnd, 2, 1000, NULL);
}

// done
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
	{
	case WM_KEYFIRST:
		switch (wParam)
		{
		case VK_F2:
			_0040B995();
			SleepFlag = 0;
			break;
		default:
			_004032D0(wParam);
			break;
		}
		return 0;
	case WM_TIMER:
        switch (wParam)
		{
		case 1:
            _0040385D();
			break;
		case 2:
            _0040BF83();
			break;
		}
		break;
	case WM_PAINT: // Paint the main window
		_0040385D();
		break;
	case WM_DESTROY: // post a quit message and return
		PostQuitMessage(0);
		break;
	case WM_ERASEBKGND:
		return 0;
	case 0x464: // 用于调试模拟器？
        _00404A08(lParam);
		break;
    }
    return DefWindowProc(hWnd, message, wParam, lParam);
}

// todo
void _00404A08(LPARAM v1)
{
    UINT32* ebp_4 = (UINT32*)v1;
    switch (ebp_4[0])
    {
    case 0://4A31
        if (_00410B28)
        {
            _0040B995();
            _00410B28 = 0;
        }
        _00410B24 = 1;
        SleepFlag = 0;
        break;
    case 1://4A62
        _00410B24 = 0;
        *(UINT32 *)ebp_4[2] = cpu.PC;
        break;
    case 2://4A7E
        _00410B24 = 0;
        if (_00410B28)
        {
            _0040B995();
            _00410B28 = 0;
        }
        _0040BAB7();
        *(UINT32 *)ebp_4[2] = cpu.PC;
        break;
    case 3://4AB7
        *(UINT32 *)ebp_4[2] = cpu.PC;
        break;
    case 4://4AC9
        _0040B995();
        *(UINT32 *)ebp_4[2] = cpu.PC;
        break;
    case 5://4AE0
        _00410AFC = ebp_4[1];
        break;
    case 9://4AF1
        _00410AF4 = ebp_4[1];
        break;
    case 6://4B02
        *(UINT32 *)ebp_4[2] = _00410C50[ebp_4[1] >> 0x13][ebp_4[1] & 0x7FFFF];
        _00410C50[ebp_4[1] >> 0x13][ebp_4[1] & 0x7FFFF] = 0x00;
        break;
    case 7://4B50
        *(UINT32 *)ebp_4[2] = ebp_4[1] + _00402FE9(ebp_4[1]) + 1;
        break;
    case 8://4B76
		{
			UINT32 ebp_C;
			if ((_00410C50[ebp_4[1] >> 0x13][ebp_4[1] & 0x7FFFF] == 0x20)
				&& (ebp_4[1] > 0x5000))
			{
				ebp_C = 1;
			}
			else
			{
				ebp_C = 0;
			}
			*(UINT32 *)ebp_4[2] = ebp_C;
		}
        break;
    case 10://4BC7
        _00410B2C = 1;
        _00410B38 = 1;
        break;
    case 11://4BE0
        *(UINT32 *)ebp_4[2] = cpu.A;
        break;
    case 12://4BEE
        _00410B20 = ebp_4[1];
        _00410B04 = *(UINT32 *)ebp_4[2];
        break;
    case 13://4C0A
		// 重置RAM，但保留0x300处的boot内容
        memset(pRam, 0, 0x300);
        memset(pRam + 0x400, 0, 0x7C00);
        _0040B7A9();
        _0040B995();
        break;
    case 14://4C46
        *(UINT32 *)ebp_4[2] = _004055B6();
        _0040B995();
        break;
    case 15://4C5A
        _0040E3F8 = ebp_4[1];
        break;
    }
    SetEvent(hEvent);
}

// done
BOOL EMU_MessageLoop()
{
    MSG msg;
    for (;;)
    {
        if (CycleCounter > 40000)
        {
            _0040BD0B(100);
            CycleCounter = 0;
        }
        if (PeekMessage(&msg, NULL, WM_NULL, WM_NULL, PM_REMOVE))
        {
            if (msg.message == 0x12)
            {
                return FALSE;
            }
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else
        {
            if (SleepFlag)
            {
                Sleep(10);
                _0040BD0B(100);
            }
            else
            {
                _0040BAB7();
                _0040BAB7();
            }
        }
    }
}

// done
void EMU_SetRunning(UINT32 v1)
{
    _00410B24 = v1;
}

// done
struct CPU *EMU_GetRegPtr()
{
    return &cpu;
}

// done
BOOL LoadRom()
{
    UINT8* ebp_4;
    CHAR ebp_84[0x80];
    CHAR ebp_104[0x80];
    CHAR ebp_208[260]; // IniFileName
    UINT8* ebp_20C;
    UINT32 ebp_210;
    CHAR ebp_314[260]; // ReturnBuffer
    UINT32 ebp_318;
    UINT32 ebp_31C; // 数据长度
    CHAR ebp_32C[0x10];
    UINT32 ebp_330; // 偏移量
    UINT32 ebp_334;
    UINT32 ebp_338; // 数据映射到基址
    CHAR ebp_348[0x10]; // Section
    UINT32 ebp_34C;
    UINT32 ebp_350;
    DWORD ebp_354;
    HANDLE ebp_358;
    CHAR ebp_45C[260];
    UINT8* ebp_460;

    _00405644();
    strcpy(ebp_208, ProgramDirectory);
    strcat(ebp_208, "A600.ini");
    ebp_318 = 0;
    for (;;)
    {
        sprintf(ebp_348, "BIN%02d", ebp_318);
		ebp_314[0] = '\0';
        GetPrivateProfileString(ebp_348, "FileName", NULL, ebp_314, sizeof(ebp_314), ebp_208);
        if (ebp_314[0] == '\0')
        {
            break;
        }
        ebp_4 = _00403070(ebp_314, 1);
        if (ebp_4 == NULL)
        {
            return 0;
        }
        ebp_210 = 0;
        for (;;)
        {
            sprintf(ebp_32C, "Segment%02d", ebp_210);
            ebp_84[0] = 0;
            GetPrivateProfileString(ebp_348, ebp_32C, NULL, ebp_84, sizeof(ebp_84), ebp_208);
            if (ebp_84[0] == '\0')
            {
                break;
            }
            sscanf(ebp_84, "%x,%x,%x,%x", &ebp_338, &ebp_330, &ebp_31C, &ebp_34C);
            if (ebp_338 >= 0x1000000 || ebp_34C < 1 || ebp_31C < ebp_330)
            {
                sprintf(ebp_104, "INI参数错误：[%s] - %s", ebp_348, ebp_32C);
                MessageBox(NULL, ebp_104, NULL, MB_OK);
                return FALSE;
            }
            ebp_20C = ebp_4 + ebp_330;
            ebp_330 >>= 0x13;
            ebp_31C >>= 0x13;
            ebp_338 >>= 0x13;
            ebp_34C -= 1;
            for (ebp_334 = 0; ebp_334 <= ebp_31C - ebp_330; ebp_334++)
            {
                _00410DDC[ebp_338 + ebp_334][ebp_34C] = ebp_20C;
                _00410C50[ebp_338 + ebp_334] = *_00410DDC[ebp_338 + ebp_334];
                ebp_20C += 0x80000;
            }
            ebp_210 += 1;
        }
        ebp_318 += 1;
    }
    ebp_314[0] = '\0';
    GetPrivateProfileString("NOMAPPING", "FileName", NULL, ebp_314, sizeof(ebp_314), ebp_208);
    if (ebp_314[0] != '\0')
    {
        if (ebp_314[1] != ':')
        {
            strcpy(ebp_45C, ProgramDirectory);
            strcat(ebp_45C, ebp_314);
            strcpy(ebp_314, ebp_45C);
        }
        ebp_358 = CreateFile(ebp_314, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
        if (ebp_358 == INVALID_HANDLE_VALUE)
        {
            return FALSE;
        }
        ebp_350 = GetFileSize(ebp_358, NULL);
        if (ebp_350 == 0)
        {
            CloseHandle(ebp_358);
            return FALSE;
        }
        ebp_460 = (UINT8*)malloc(ebp_350);
        lpNoMappingFileBuffer = ebp_460;
        if (lpNoMappingFileBuffer == NULL)
        {
            CloseHandle(ebp_358);
            return FALSE;
        }
        if (ReadFile(ebp_358, lpNoMappingFileBuffer, ebp_350, &ebp_354, NULL) == NULL)
        {
            CloseHandle(ebp_358);
            return FALSE;
        }
        CloseHandle(ebp_358);
        if (ebp_350 != ebp_354)
        {
            return FALSE;
        }
        strcpy(NoMappingFileName, ebp_314);
        NoMappingFileSize = ebp_350;
        UINT32 ebp_210 = 0;
        for (;;)
        {
            sprintf(ebp_32C, "Segment%02d", ebp_210);
            ebp_84[0] = 0;
            GetPrivateProfileString("NOMAPPING", ebp_32C, NULL, ebp_84, sizeof(ebp_84), ebp_208);
            if (!ebp_84[0])
            {
                break;
            }
            sscanf(ebp_84, "%x,%x,%x,%x", &ebp_338, &ebp_330, &ebp_31C, &ebp_34C);
            if (ebp_338 >= 0x1000000 || ebp_34C < 1 || ebp_31C < ebp_330)
            {
                sprintf(ebp_104, "INI参数错误：[%s] - %s", ebp_348, ebp_32C);
                MessageBox(NULL, ebp_104, NULL, MB_OK);
                return FALSE;
            }
            ebp_20C = lpNoMappingFileBuffer + ebp_330;
            ebp_330 >>= 0x13;
            ebp_31C >>= 0x13;
            ebp_338 >>= 0x13;
            ebp_34C -= 1;
            for (ebp_334 = 0; ebp_334 <= ebp_31C - ebp_330; ebp_334++)
            {
                _00410DDC[ebp_338 + ebp_334][ebp_34C] = ebp_20C;
                _00410C50[ebp_338 + ebp_334] = *_00410DDC[ebp_338 + ebp_334];
                ebp_20C += 0x80000;
            }
            ebp_210 += 1;
        }
    }
    GetPrivateProfileString("FLASH", "StartAdr", NULL, ebp_84, sizeof(ebp_84), ebp_208);
    if (ebp_84[0] != '\0')
    {
        sscanf(ebp_84, "%x", &FlashStartAdr);
        ebp_84[0] = '\0';
    }
    GetPrivateProfileString("FLASH", "Size", NULL, ebp_84, sizeof(ebp_84), ebp_208);
    if (ebp_84[0] != '\0')
    {
        sscanf(ebp_84, "%x", &FlashSize);
        ebp_84[0] = '\0';
    }
    GetPrivateProfileString("DEBUG", "BaseAdr", NULL, ebp_84, sizeof(ebp_84), ebp_208);
    if (ebp_84[0] != '\0')
    {
        sscanf(ebp_84, "%x", &DebugBaseAdr);
        ebp_84[0] = '\0';
    }
    GetPrivateProfileString("DEBUG", "NumOfBank", NULL, ebp_84, sizeof(ebp_84), ebp_208);
    if (ebp_84[0] != '\0')
    {
        sscanf(ebp_84, "%d", &DebugNumOfBank);
    }
    FlashEndAdr = FlashStartAdr + FlashSize;
    pFlashMemory = _00410C50[FlashStartAdr >> 0x13];
    if (pFlashMemory == NULL)
    {
        MessageBox(NULL, "未配置FLASH", NULL, MB_OK);
        return FALSE;
    }
	// 复制boot部分代码到0x300处
    memcpy(pRam + 0x300, _00410C50[0x1F] + 0x7FF00, 0x100);
    return TRUE;
}

// done
void _00405558()
{
    _00403260();
    if (pRam != NULL)
    {
        UINT8* ebp_4 = pRam;
        free(ebp_4);
        pRam = NULL;
    }
    if (lpNoMappingFileBuffer != NULL)
    {
        UINT8* ebp_8 = lpNoMappingFileBuffer;
        free(ebp_8);
        lpNoMappingFileBuffer = NULL;
    }
}

// done
BOOL _004055B6()
{
    if (lpNoMappingFileBuffer == NULL)
    {
        return TRUE;
    }
    FILE* ebp_4 = fopen(NoMappingFileName, "rb");
    if (ebp_4 == NULL)
    {
        return FALSE;
    }
    fread(lpNoMappingFileBuffer, NoMappingFileSize, 1, ebp_4);
    fclose(ebp_4);
	// 复制boot部分代码到0x300处
    memcpy(pRam + 0x300, _00410C50[0x1F] + 0x7FF00, 0x100);
    return TRUE;
}

// 获取程序所在目录
void _00405644()
{
	char *ebp_4 = ProgramDirectory;
	char *ebp_8 = ebp_4;
	GetModuleFileName(NULL, ProgramDirectory, 260);
	while (*ebp_4)
	{
		if ((*ebp_4) == '\\')
		{
			ebp_8 = ebp_4;
		}
		ebp_4++;
	}
	*(ebp_8+1) = '\0';
}

// done
void _0040569A()
{
	__try
	{
		if ((_00413A70<FlashEndAdr) && (_00413A70>=FlashStartAdr))
		{
			_00412204 = ReadFlash(_00413A70-FlashStartAdr);
		}
		else
		{
			_00412204 = _00410C50[_00413A70>>0x13][_00413A70&0x7FFFF];
		}
	}
	__except (EXCEPTION_EXECUTE_HANDLER)
	{
		char ebp_98[0x80];
		AbsoluteAddress = BankAddressList[cpu.PC>>0x0C] | (cpu.PC&0x0FFF);
		sprintf(ebp_98, "读无效地址:%08x\nPC=%04X(%06X) PB=%02X", _00413A70, cpu.PC, AbsoluteAddress, pRam[0x21B]);
		MessageBox(NULL, ebp_98, NULL, MB_OK);
	}
}

// 写数据
void _004057C3()
{
	__try
	{
		if ((_00413A70<FlashEndAdr) && (_00413A70>=FlashStartAdr))
		{
			WriteFlash(_00413A70-FlashStartAdr, _00412204);
		}
		else
		{
			_00410C50[_00413A70>>0x13][_00413A70&0x7FFFF] = _00412204;
		}
	}
	__except (EXCEPTION_EXECUTE_HANDLER)
	{
		char ebp_98[0x80];
		AbsoluteAddress = BankAddressList[cpu.PC>>0x0C] | (cpu.PC&0x0FFF);
		sprintf(ebp_98, "写无效地址:%08x\nPC=%04X(%06X) PB=%02X", _00413A70, cpu.PC, AbsoluteAddress, pRam[0x21B]);
		MessageBox(NULL, ebp_98, NULL, MB_OK);
	}
}

// done
UINT32 _004058E7(UINT32 v1)
{
    return _0040BA29(v1>>0x0C)|(v1&0x0FFF);
}

// done
UINT32 MEM_ConvertAdr(UINT32 v1)
{
	if (v1<0xD000)
	{
		return v1;
	}
	else if (v1<0x10000)
	{
		v1 += DebugBaseAdr - 0x5000;
	}
	else
	{
		UINT32 ebp_8 = v1>>0x10;
		UINT32 ebp_4 = ebp_8 * _00410C4C;
		UINT32 ebp_10 = 0x5000;
		UINT32 ebp_C = (v1&0xFFFF) - ebp_10;
		v1 = (ebp_4<<0x0C) + ebp_C;
		v1 += DebugBaseAdr;
	}
	return v1;
}

// done
void MEM_Poke(UINT32 v1, UINT32 v2)
{
    UINT32 ebp_4 = v1>>0x13;
	if (_00410C50[ebp_4] && (ebp_4 || (v1<0x8000)))
	{
		_00410C50[ebp_4][v1&0x7FFFF] = v2;
	}
}

// done
UINT32 MEM_Peek(UINT32 v1)
{
    UINT32 ebp_4 = v1>>0x13;
	if (_00410C50[ebp_4] && (ebp_4 || (v1<0x8000)))
	{
		return _00410C50[ebp_4][v1&0x7FFFF];
	}
	return 0;
}

// done
void MEM_PokeL(UINT32 v1, UINT32 v2)
{
    v1 = _0040BA29(v1>>0x0C) | (v1&0x0FFF);
	MEM_Poke(v1, v2);
}

// done
UINT32 MEM_PeekL(UINT32 v1)
{
    v1 = _0040BA29(v1>>0x0C) | (v1&0x0FFF);
	return MEM_Peek(v1);
}

// done
void _00405A80()
{
	UINT32 ebp_4 = _00412204&0x40 ? 1 : 0;
    for (INT32 ebp_8=0; ebp_8<8; ebp_8++)
	{
		_00410C50[ebp_8+8] = _00410DDC[ebp_8+8][ebp_4];
	}
}

// done
void _00405AD2()
{
    if ((_00412204&0xC0) == 0x80)
	{
		_00403802((UINT8)_00412204&0x3F);
	}
}

// done
BOOL AllocMemory()
{
    memset(_00410C50, 0, sizeof(_00410C50));
    memset(_00410DDC, 0, sizeof(_00410DDC));
    pRam = (UINT8*)malloc(0x8000);
    if (NULL == pRam)
    {
        return FALSE;
    }
    memset(pRam, 0, 0x8000);
    _00410C50[0] = pRam;
    switch (_00401000())
    {
	case 0:
        FlashSize = 0x100000; // 1MB
		break;
	case 1:
        FlashSize = 0x200000; // 2MB
		break;
	case 2:
        FlashSize = 0x400000; // 4MB
		break;
    }
    FlashStartAdr = 0x200000;
    FlashEndAdr = FlashStartAdr + FlashSize;
    _0040B7A9();
    _00408EF2(0x21B, _00405A80); // _PB
    _00408EF2(0x218, _00405AD2); // _PA
    return _00403020();
}

// done
void AddressingModeNop()
{
    // VOID
}

// done
void AddressingModeImmediate()
{
    _004121FC = cpu.PC++;
}

// done
void AddressingModeAbsolute()
{
	 UINT32 ebp_4 = BankAddressList[cpu.PC>>0x0C] | (cpu.PC&0x0FFF);
	 cpu.PC += 2;
	 _004121FC = *(UINT16 *)&_00410C50[ebp_4>>0x13][ebp_4&0x7FFFF];
}

// done
void AddressingModeNone()
{
    _004121FC = cpu.PC++;
}

// done
void AddressingModeIndirect()
{
	UINT32 ebp_4 = BankAddressList[cpu.PC>>0x0C] | (cpu.PC&0x0FFF);
	cpu.PC += 1;
	_00412204 = _00410C50[ebp_4>>0x13][ebp_4&0x7FFFF];
	_004121FC = *(UINT16 *)(pRam+_00412204);
}

// done
void AddressingModeAbsoluteX()
{
	UINT32 ebp_4 = BankAddressList[cpu.PC>>0x0C] | (cpu.PC&0x0FFF);
	cpu.PC += 2;
	_004121FC = *(UINT16 *)&_00410C50[ebp_4>>0x13][ebp_4&0x7FFFF];
	_004121FC += cpu.X;
}

// done
void AddressingModeAbsoluteY()
{
	UINT32 ebp_4 = BankAddressList[cpu.PC>>0x0C] | (cpu.PC&0x0FFF);
	cpu.PC += 2;
	_004121FC = *(UINT16 *)&_00410C50[ebp_4>>0x13][ebp_4&0x7FFFF];
	_004121FC += cpu.Y;
}

// done
void AddressingModeZeroPage()
{
	UINT32 ebp_4 = BankAddressList[cpu.PC>>0x0C] | (cpu.PC&0x0FFF);
	cpu.PC += 1;
	_004121FC = _00410C50[ebp_4>>0x13][ebp_4&0x7FFFF];
}

// done
void AddressingModeZeroPageX()
{
	UINT32 ebp_4 = BankAddressList[cpu.PC>>0x0C] | (cpu.PC&0x0FFF);
	cpu.PC += 1;
	_004121FC = _00410C50[ebp_4>>0x13][ebp_4&0x7FFFF];
	_004121FC += cpu.X;
	_004121FC &= 0xFF;
}

// done
void AddressingModeZeroPageY()
{
	UINT32 ebp_4 = BankAddressList[cpu.PC>>0x0C] | (cpu.PC&0x0FFF);
	cpu.PC += 1;
	_004121FC = _00410C50[ebp_4>>0x13][ebp_4&0x7FFFF];
	_004121FC += cpu.Y;
	_004121FC &= 0xFF;
}

// done
void AddressingModeIndirectX()
{
	UINT32 ebp_4 = BankAddressList[cpu.PC>>0x0C] | (cpu.PC&0x0FFF);
	cpu.PC += 1;
	_004121FC = _00410C50[ebp_4>>0x13][ebp_4&0x7FFFF];
	_004121FC += cpu.X;
	_004121FC &= 0xFF;
	_004121FC = *(UINT16 *)&pRam[_004121FC];
}

// done
void AddressingModeIndirectY()
{
	UINT32 ebp_4 = BankAddressList[cpu.PC>>0x0C] | (cpu.PC&0x0FFF);
	cpu.PC += 1;
	_004121FC = _00410C50[ebp_4>>0x13][ebp_4&0x7FFFF];
	_004121FC = *(UINT16 *)&pRam[_004121FC];
	_004121FC += cpu.Y;
}

// done
void InstructionAdc()
{
	_0040C190();
	INT32 ebp_4 = cpu.A;
	ebp_4 += _00412204;
	ebp_4 += (cpu.P & 0x01);
	if (ebp_4 > 0xFF)
	{
		cpu.P |= 0x40;
	}
	else
	{
		cpu.P &= 0xBF;
	}
	if (ebp_4 > 0xFF)
	{
		cpu.P |= 0x01;
	}
	else
	{
		cpu.P &= 0xFE;
	}
	cpu.A = ebp_4 & 0xFF;
	if (cpu.P & 0x08)
	{
		cpu.P &= 0xFE;
		if ((cpu.A&0x0F) > 0x09)
		{
			cpu.A += 0x06;
		}
		if ((cpu.A&0xF0) > 0x90)
		{
			cpu.A += 0x60;
			cpu.P |= 0x01;
		}
	}
	if (cpu.A)
	{
		cpu.P &= 0xFD;
	}
	else
	{
		cpu.P |= 0x02;
	}
	if (cpu.A & 0x80)
	{
		cpu.P |= 0x80;
	}
	else
	{
		cpu.P &= 0x7F;
	}
}

// AND
void InstructionAnd()
{
	_0040C190();
	cpu.A &= _00412204;
	if (cpu.A)
	{
		cpu.P &= 0xFD;
	}
	else
	{
		cpu.P |= 0x02;
	}
	if (cpu.A & 0x80)
	{
		cpu.P |= 0x80;
	}
	else
	{
		cpu.P &= 0x7F;
	}
}

// done
void InstructionAsl()
{
	_0040C190();
	cpu.P = (cpu.P&0xFE) | ((_00412204>>7)&0x01);
	_00412204 <<= 1;
	_00412204 &= 0xFF;
	_0040C1E0();
	if (_00412204)
	{
		cpu.P &= 0xFD;
	}
	else
	{
		cpu.P |= 0x02;
	}
	if (_00412204 & 0x80)
	{
		cpu.P |= 0x80;
	}
	else
	{
		cpu.P &= 0x7F;
	}
}

// done
void InstructionAsl_A()
{
	cpu.P = (cpu.P&0xFE) | ((cpu.A>>7)&0x01);
	cpu.A <<= 1;
	cpu.A &= 0xFF;
	if (cpu.A)
	{
		cpu.P &= 0xFD;
	}
	else
	{
		cpu.P |= 0x02;
	}
	if (cpu.A & 0x80)
	{
		cpu.P |= 0x80;
	}
	else
	{
		cpu.P &= 0x7F;
	}
}

// done
void InstructionBbr0()
{
	_0040C190();
	UINT32 ebp_4 = *(UINT32 *)(pRam + _00412204);
	_0040C190();
	if ((ebp_4&0x01) == 0x00)
	{
		cpu.PC += _00412204;
		if (_00412204>0x7F)
		{
			cpu.PC -= 0x100;
		}
	}
}

// done
void InstructionBbr1()
{
	_0040C190();
	UINT32 ebp_4 = *(UINT32 *)(pRam + _00412204);
	_0040C190();
	if ((ebp_4&0x02) == 0x00)
	{
		cpu.PC += _00412204;
		if (_00412204>0x7F)
		{
			cpu.PC -= 0x100;
		}
	}
}

// done
void InstructionBbr2()
{
	_0040C190();
	UINT32 ebp_4 = *(UINT32 *)(pRam + _00412204);
	_0040C190();
	if ((ebp_4&0x04) == 0x00)
	{
		cpu.PC += _00412204;
		if (_00412204>0x7F)
		{
			cpu.PC -= 0x100;
		}
	}
}

// done
void InstructionBbr3()
{
	_0040C190();
	UINT32 ebp_4 = *(UINT32 *)(pRam + _00412204);
	_0040C190();
	if ((ebp_4&0x08) == 0x00)
	{
		cpu.PC += _00412204;
		if (_00412204>0x7F)
		{
			cpu.PC -= 0x100;
		}
	}
}

// done
void InstructionBbr4()
{
	_0040C190();
	UINT32 ebp_4 = *(UINT32 *)(pRam + _00412204);
	_0040C190();
	if ((ebp_4&0x10) == 0x00)
	{
		cpu.PC += _00412204;
		if (_00412204>0x7F)
		{
			cpu.PC -= 0x100;
		}
	}
}

// done
void InstructionBbr5()
{
	_0040C190();
	UINT32 ebp_4 = *(UINT32 *)(pRam + _00412204);
	_0040C190();
	if ((ebp_4&0x20) == 0x00)
	{
		cpu.PC += _00412204;
		if (_00412204>0x7F)
		{
			cpu.PC -= 0x100;
		}
	}
}

// done
void InstructionBbr6()
{
	_0040C190();
	UINT32 ebp_4 = *(UINT32 *)(pRam + _00412204);
	_0040C190();
	if ((ebp_4&0x40) == 0x00)
	{
		cpu.PC += _00412204;
		if (_00412204>0x7F)
		{
			cpu.PC -= 0x100;
		}
	}
}

// done
void InstructionBbr7()
{
	_0040C190();
	UINT32 ebp_4 = *(UINT32 *)(pRam + _00412204);
	_0040C190();
	if ((ebp_4&0x80) == 0x00)
	{
		cpu.PC += _00412204;
		if (_00412204>0x7F)
		{
			cpu.PC -= 0x100;
		}
	}
}

// done
void InstructionBbs0()
{
	_0040C190();
	UINT32 ebp_4 = *(UINT32 *)(pRam + _00412204);
	_0040C190();
	if (ebp_4&0x01)
	{
		cpu.PC += _00412204;
		if (_00412204>0x7F)
		{
			cpu.PC -= 0x100;
		}
	}
}

// done
void InstructionBbs1()
{
	_0040C190();
	UINT32 ebp_4 = *(UINT32 *)(pRam + _00412204);
	_0040C190();
	if (ebp_4&0x02)
	{
		cpu.PC += _00412204;
		if (_00412204>0x7F)
		{
			cpu.PC -= 0x100;
		}
	}
}

// done
void InstructionBbs2()
{
	_0040C190();
	UINT32 ebp_4 = *(UINT32 *)(pRam + _00412204);
	_0040C190();
	if (ebp_4&0x04)
	{
		cpu.PC += _00412204;
		if (_00412204>0x7F)
		{
			cpu.PC -= 0x100;
		}
	}
}

// done
void InstructionBbs3()
{
	_0040C190();
	UINT32 ebp_4 = *(UINT32 *)(pRam + _00412204);
	_0040C190();
	if (ebp_4&0x08)
	{
		cpu.PC += _00412204;
		if (_00412204>0x7F)
		{
			cpu.PC -= 0x100;
		}
	}
}

// done
void InstructionBbs4()
{
	_0040C190();
	UINT32 ebp_4 = *(UINT32 *)(pRam + _00412204);
	_0040C190();
	if (ebp_4&0x10)
	{
		cpu.PC += _00412204;
		if (_00412204>0x7F)
		{
			cpu.PC -= 0x100;
		}
	}
}

// done
void InstructionBbs5()
{
	_0040C190();
	UINT32 ebp_4 = *(UINT32 *)(pRam + _00412204);
	_0040C190();
	if (ebp_4&0x20)
	{
		cpu.PC += _00412204;
		if (_00412204>0x7F)
		{
			cpu.PC -= 0x100;
		}
	}
}

// done
void InstructionBbs6()
{
	_0040C190();
	UINT32 ebp_4 = *(UINT32 *)(pRam + _00412204);
	_0040C190();
	if (ebp_4&0x40)
	{
		cpu.PC += _00412204;
		if (_00412204>0x7F)
		{
			cpu.PC -= 0x100;
		}
	}
}

// done
void InstructionBbs7()
{
	_0040C190();
	UINT32 ebp_4 = *(UINT32 *)(pRam + _00412204);
	_0040C190();
	if (ebp_4&0x80)
	{
		cpu.PC += _00412204;
		if (_00412204>0x7F)
		{
			cpu.PC -= 0x100;
		}
	}
}

// done
void InstructionBcc()
{
	if ((cpu.P&0x01) == 0x00)
	{
		_0040C190();
		cpu.PC += _00412204;
		if (_00412204>0x7F)
		{
			cpu.PC -= 0x100;
		}
	}
}

// done
void InstructionBcs()
{
	if (cpu.P&0x01)
	{
		_0040C190();
		cpu.PC += _00412204;
		if (_00412204>0x7F)
		{
			cpu.PC -= 0x100;
		}
	}
}

// done
void InstructionBeq()
{
	if (cpu.P&0x02)
	{
		_0040C190();
		cpu.PC += _00412204;
		if (_00412204>0x7F)
		{
			cpu.PC -= 0x100;
		}
	}
}

// done
void InstructionBit()
{
	_0040C190();
	if (_00412204&cpu.A)
	{
		cpu.P &= 0xFD;
	}
	else
	{
		cpu.P |= 0x02;
	}
	cpu.P = (cpu.P&0x3F)|(_00412204&0xC0);
}

// done
void InstructionBmi()
{
    if (cpu.P&0x80)
	{
		_0040C190();
		cpu.PC += _00412204;
		if (_00412204>0x7F)
		{
			cpu.PC -= 0x100;
		}
	}
}

// done
void InstructionBne()
{
	if ((cpu.P&0x02) == 0x00)
	{
		_0040C190();
		cpu.PC += _00412204;
		if (_00412204>0x7F)
		{
			cpu.PC -= 0x100;
		}
	}
}

// done
void InstructionBpl()
{
	if ((cpu.P&0x80) == 0x00)
	{
		_0040C190();
		cpu.PC += _00412204;
		if (_00412204>0x7F)
		{
			cpu.PC -= 0x100;
		}
	}
}

// done
void InstructionBra()
{
	_0040C190();
	cpu.PC += _00412204;
	if (_00412204>0x7F)
	{
		cpu.PC -= 0x100;
	}
}

// done
void InstructionUnknown()
{
	char ebp_80[0x80];
#ifdef _DEBUG
	debug_save_regedits();
#endif
    cpu.PC--;
	AbsoluteAddress = BankAddressList[cpu.PC>>0x0C] | (cpu.PC&0x0FFF);
	sprintf(ebp_80, "PC=%04X(%06X) PB=%02X", cpu.PC, AbsoluteAddress, pRam[0x21B]);
	MessageBox(NULL, ebp_80, "程序跑飞!", MB_OK);
	_0040B995();
}

// done
void InstructionBvc()
{
	if ((cpu.P&0x40) == 0x00)
	{
		_0040C190();
		cpu.PC += _00412204;
		if (_00412204 > 0x7F)
		{
			cpu.PC -= 0x100;
		}
	}
}

// done
void InstructionBvs()
{
	if (cpu.P&0x40)
	{
		_0040C190();
		cpu.PC += _00412204;
		if (_00412204 > 0x7F)
		{
			cpu.PC -= 0x100;
		}
	}
}

// done
void InstructionClc()
{
    cpu.P &= 0xFE;
}

// done
void InstructionCld()
{
    cpu.P &= 0xF7;
}

// done
void InstructionCli()
{
    cpu.P &= 0xFB;
}

// done
void InstructionClv()
{
    cpu.P &= 0xBF;
}

// done
void InstructionCmp()
{
	_0040C190();
	if ((cpu.A+0x100-_00412204) > 0xFF)
	{
		cpu.P |= 0x01;
	}
	else
	{
		cpu.P &= 0xFE;
	}
	_00412204 = (cpu.A+0x100-_00412204) & 0xFF;
	if (_00412204)
	{
		cpu.P &= 0xFD;
	}
	else
	{
		cpu.P |= 0x02;
	}
	if (_00412204&0x80)
	{
		cpu.P |= 0x80;
	}
	else
	{
		cpu.P &= 0x7F;
	}
}

// done
void InstructionCpx()
{
	_0040C190();
	if ((cpu.X+0x100-_00412204) > 0xFF)
	{
		cpu.P |= 0x01;
	}
	else
	{
		cpu.P &= 0xFE;
	}
	_00412204 = (cpu.X+0x100-_00412204) & 0xFF;
	if (_00412204)
	{
		cpu.P &= 0xFD;
	}
	else
	{
		cpu.P |= 0x02;
	}
	if (_00412204&0x80)
	{
		cpu.P |= 0x80;
	}
	else
	{
		cpu.P &= 0x7F;
	}
}

// done
void InstructionCpy()
{
	_0040C190();
	if ((cpu.Y+0x100-_00412204) > 0xFF)
	{
		cpu.P |= 0x01;
	}
	else
	{
		cpu.P &= 0xFE;
	}
	_00412204 = (cpu.Y+0x100-_00412204) & 0xFF;
	if (_00412204)
	{
		cpu.P &= 0xFD;
	}
	else
	{
		cpu.P |= 0x02;
	}
	if (_00412204&0x80)
	{
		cpu.P |= 0x80;
	}
	else
	{
		cpu.P &= 0x7F;
	}
}

// done
void InstructionDec_A()
{
	cpu.A--;
	cpu.A &= 0xFF;
	if (cpu.A)
	{
		cpu.P &= 0xFD;
	}
	else
	{
		cpu.P |= 0x02;
	}
	if (cpu.A&0x80)
	{
		cpu.P |= 0x80;
	}
	else
	{
		cpu.P &= 0x7F;
	}
}

// done
void InstructionDec()
{
	_0040C190();
	_00412204--;
	_0040C1E0();
	if (_00412204)
	{
		cpu.P &= 0xFD;
	}
	else
	{
		cpu.P |= 0x02;
	}
	if (_00412204&0x80)
	{
		cpu.P |= 0x80;
	}
	else
	{
		cpu.P &= 0x7F;
	}
}

// done
void InstructionDex()
{
	cpu.X--;
	cpu.X &= 0xFF;
	if (cpu.X)
	{
		cpu.P &= 0xFD;
	}
	else
	{
		cpu.P |= 0x02;
	}
	if (cpu.X&0x80)
	{
		cpu.P |= 0x80;
	}
	else
	{
		cpu.P &= 0x7F;
	}
}

// done
void InstructionDey()
{
	cpu.Y--;
	cpu.Y &= 0xFF;
	if (cpu.Y)
	{
		cpu.P &= 0xFD;
	}
	else
	{
		cpu.P |= 0x02;
	}
	if (cpu.Y&0x80)
	{
		cpu.P |= 0x80;
	}
	else
	{
		cpu.P &= 0x7F;
	}
}

// done
void InstructionEor()
{
	_0040C190();
	cpu.A ^= _00412204;
	if (cpu.A)
	{
		cpu.P &= 0xFD;
	}
	else
	{
		cpu.P |= 0x02;
	}
	if (cpu.A&0x80)
	{
		cpu.P |= 0x80;
	}
	else
	{
		cpu.P &= 0x7F;
	}
}

// done
void InstructionInc_A()
{
	cpu.A++;
	cpu.A &= 0xFF;
	if (cpu.A)
	{
		cpu.P &= 0xFD;
	}
	else
	{
		cpu.P |= 0x02;
	}
	if (cpu.A&0x80)
	{
		cpu.P |= 0x80;
	}
	else
	{
		cpu.P &= 0x7F;
	}
}

// done
void InstructionInc()
{
	_0040C190();
	_00412204++;
	_00412204 &= 0xFF;
	_0040C1E0();
	if (_00412204)
	{
		cpu.P &= 0xFD;
	}
	else
	{
		cpu.P |= 0x02;
	}
	if (_00412204&0x80)
	{
		cpu.P |= 0x80;
	}
	else
	{
		cpu.P &= 0x7F;
	}
}

// done
void InstructionInx()
{
	cpu.X++;
	cpu.X &= 0xFF;
	if (cpu.X)
	{
		cpu.P &= 0xFD;
	}
	else
	{
		cpu.P |= 0x02;
	}
	if (cpu.X&0x80)
	{
		cpu.P |= 0x80;
	}
	else
	{
		cpu.P &= 0x7F;
	}
}

// done
void InstructionIny()
{
	cpu.Y++;
	cpu.Y &= 0xFF;
	if (cpu.Y)
	{
		cpu.P &= 0xFD;
	}
	else
	{
		cpu.P |= 0x02;
	}
	if (cpu.Y&0x80)
	{
		cpu.P |= 0x80;
	}
	else
	{
		cpu.P &= 0x7F;
	}
}

// done
void InstructionJmp()
{
	cpu.PC = _004121FC;
}

// done
void InstructionJsr()
{
	UINT32 ebp_4 = cpu.PC;
	cpu.PC = _004121FC;
	ebp_4--;
	cpu.S -= 2;
	*(UINT16 *)(pRam + cpu.S + 1) = ebp_4;
}

// done
void InstructionLda()
{
	_0040C190();
	cpu.A = _00412204;
	if (cpu.A)
	{
		cpu.P &= 0xFD;
	}
	else
	{
		cpu.P |= 0x02;
	}
	if (cpu.A & 0x80)
	{
		cpu.P |= 0x80;
	}
	else
	{
		cpu.P &= 0x7F;
	}
}

// done
void InstructionLdx()
{
	_0040C190();
	cpu.X = _00412204;
	if (cpu.X)
	{
		cpu.P &= 0xFD;
	}
	else
	{
		cpu.P |= 0x02;
	}
	if (cpu.X & 0x80)
	{
		cpu.P |= 0x80;
	}
	else
	{
		cpu.P &= 0x7F;
	}
}

// done
void InstructionLdy()
{
	_0040C190();
	cpu.Y = _00412204;
	if (cpu.Y)
	{
		cpu.P &= 0xFD;
	}
	else
	{
		cpu.P |= 0x02;
	}
	if (cpu.Y & 0x80)
	{
		cpu.P |= 0x80;
	}
	else
	{
		cpu.P &= 0x7F;
	}
}

// done
void InstructionLsr()
{
	_0040C190();
	cpu.P = (cpu.P & 0xFE) | (_00412204 & 0x01);
	_00412204 >>= 1;
	_0040C1E0();
	if (_00412204)
	{
		cpu.P &= 0xFD;
	}
	else
	{
		cpu.P |= 0x02;
	}
	if (_00412204 & 0x80)
	{
		cpu.P |= 0x80;
	}
	else
	{
		cpu.P &= 0x7F;
	}
}

// done
void InstructionLsr_A()
{
	cpu.P = (cpu.P & 0xFE) | (cpu.A & 0x01);
	cpu.A >>= 1;
	if (cpu.A)
	{
		cpu.P &= 0xFD;
	}
	else
	{
		cpu.P |= 0x02;
	}
	if (cpu.A & 0x80)
	{
		cpu.P |= 0x80;
	}
	else
	{
		cpu.P &= 0x7F;
	}
}

// NOP
void InstructionNop()
{
    // VOID
}

// done
void InstructionOra()
{
	_0040C190();
    cpu.A |= _00412204;
	if (cpu.A)
	{
		cpu.P &= 0xFD;
	}
	else
	{
		cpu.P |= 0x02;
	}
	if (cpu.A & 0x80)
	{
		cpu.P |= 0x80;
	}
	else
	{
		cpu.P &= 0x7F;
	}
}

// done
void InstructionPha()
{
    pRam[cpu.S] = cpu.A;
	cpu.S--;
}

// done
void InstructionPhp()
{
    pRam[cpu.S] = cpu.P;
	cpu.S--;
}

// done
void InstructionPhx()
{
    pRam[cpu.S] = cpu.X;
	cpu.S--;
}

// done
void InstructionPhy()
{
    pRam[cpu.S] = cpu.Y;
	cpu.S--;
}

// done
void InstructionPla()
{
	cpu.S++;
	cpu.A = pRam[cpu.S];
	if (cpu.A)
	{
		cpu.P &= 0xFD;
	}
	else
	{
		cpu.P |= 0x02;
	}
	if (cpu.A & 0x80)
	{
		cpu.P |= 0x80;
	}
	else
	{
		cpu.P &= 0x7F;
	}
}

// done
void InstructionPlp()
{
	cpu.S++;
	cpu.P = pRam[cpu.S];
}

// done
void InstructionPlx()
{
	cpu.S++;
	cpu.X = pRam[cpu.S];
	if (cpu.X)
	{
		cpu.P &= 0xFD;
	}
	else
	{
		cpu.P |= 0x02;
	}
	if (cpu.X & 0x80)
	{
		cpu.P |= 0x80;
	}
	else
	{
		cpu.P &= 0x7F;
	}
}

// done
void InstructionPly()
{
	cpu.S++;
	cpu.Y = pRam[cpu.S];
	if (cpu.Y)
	{
		cpu.P &= 0xFD;
	}
	else
	{
		cpu.P |= 0x02;
	}
	if (cpu.Y & 0x80)
	{
		cpu.P |= 0x80;
	}
	else
	{
		cpu.P &= 0x7F;
	}
}

// done
void InstructionRol()
{
	_0040C190();
	UINT32 ebp_4 = cpu.P & 0x01;
	cpu.P = (cpu.P&0xFE)|((_00412204>>0x07)&0x01);
	_00412204 <<= 1;
	_00412204 |= ebp_4;
	_0040C1E0();
	if (_00412204)
	{
		cpu.P &= 0xFD;
	}
	else
	{
		cpu.P |= 0x02;
	}
	if (_00412204 & 0x80)
	{
		cpu.P |= 0x80;
	}
	else
	{
		cpu.P &= 0x7F;
	}
}

// done
void InstructionRol_A()
{
	UINT32 ebp_4 = cpu.P & 0x01;
	cpu.P = (cpu.P&0xFE)|((cpu.A>>0x07)&0x01);
	cpu.A <<= 1;
	cpu.A &= 0xFF;
	cpu.A |= ebp_4;
	if (cpu.A)
	{
		cpu.P &= 0xFD;
	}
	else
	{
		cpu.P |= 0x02;
	}
	if (cpu.A & 0x80)
	{
		cpu.P |= 0x80;
	}
	else
	{
		cpu.P &= 0x7F;
	}
}

// done
void InstructionRor()
{
	_0040C190();
	UINT32 ebp_4 = cpu.P & 0x01;
	cpu.P = (cpu.P&0xFE)|(_00412204&0x01);
	_00412204 >>= 1;
	if (ebp_4)
	{
		_00412204 |= 0x80;
	}
	_0040C1E0();
	if (_00412204)
	{
		cpu.P &= 0xFD;
	}
	else
	{
		cpu.P |= 0x02;
	}
	if (_00412204 & 0x80)
	{
		cpu.P |= 0x80;
	}
	else
	{
		cpu.P &= 0x7F;
	}
}

// done
void InstructionRor_A()
{
	UINT32 ebp_4 = cpu.P & 0x01;
	cpu.P = (cpu.P&0xFE)|(cpu.A&0x01);
	cpu.A >>= 1;
	if (ebp_4)
	{
		cpu.A |= 0x80;
	}
	if (cpu.A)
	{
		cpu.P &= 0xFD;
	}
	else
	{
		cpu.P |= 0x02;
	}
	if (cpu.A & 0x80)
	{
		cpu.P |= 0x80;
	}
	else
	{
		cpu.P &= 0x7F;
	}
}

// done
void InstructionRti()
{
	UINT32 ebp_4 = *(UINT32 *)(pRam + cpu.S + 1);
	cpu.P = ebp_4 & 0xFF;
	cpu.PC = (ebp_4 >> 8)&0xFFFF;
	cpu.S += 3;
}

// done
void InstructionRts()
{
	cpu.PC = *(UINT16 *)(pRam + cpu.S + 1) + 1;
	cpu.S += 2;
}

// done
void InstructionSbc()
{
	_0040C190();
	_00412204 ^= 0xFF;
	UINT32 ebp_4 = cpu.P & 0x01;
	INT32 ebp_8 = (INT8)cpu.A + (INT8)_00412204 + (ebp_4 << 4);
	if ((ebp_8>0x7F) || (ebp_8<(-0x80)))
	{
		cpu.P |= 0x40;
	}
	else
	{
		cpu.P &= 0xBF;
	}
	ebp_8 = cpu.A + _00412204 + ebp_4;
	if (ebp_8 > 0xFF)
	{
		cpu.P |= 0x01;
	}
	else
	{
		cpu.P &= 0xFE;
	}
	cpu.A = ebp_8 & 0xFF;
	if (cpu.P & 0x08)
	{
		cpu.A -= 0x66;
		cpu.A &= 0xFF;
		cpu.P &= 0xFE;
		if ((cpu.A&0x0F) > 0x09)
		{
			cpu.A += 0x06;
		}
		if ((cpu.A&0xF0) > 0x90)
		{
			cpu.A += 0x60;
			cpu.A &= 0xFF;
			cpu.P |= 0x01;
		}
	}
	if (cpu.A)
	{
		cpu.P &= 0xFD;
	}
	else
	{
		cpu.P |= 0x02;
	}
	if (cpu.A & 0x80)
	{
		cpu.P |= 0x80;
	}
	else
	{
		cpu.P &= 0x7F;
	}
}

// done
void InstructionSec()
{
    cpu.P |= 0x01;
}

// done
void InstructionSed()
{
    cpu.P |= 0x08;
}

// done
void InstructionSei()
{
    cpu.P |= 0x04;
}

// done
void InstructionSta()
{
    _00412204 = cpu.A;
	_0040C1E0();
}

// done
void InstructionStx()
{
    _00412204 = cpu.X;
	_0040C1E0();
}

// done
void InstructionSty()
{
    _00412204 = cpu.Y;
	_0040C1E0();
}

// done
void InstructionStz()
{
    _00412204 = 0;
	_0040C1E0();
}

// done
void InstructionTax()
{
    cpu.X = cpu.A;
	if (cpu.X)
	{
		cpu.P &= 0xFD;
	}
	else
	{
		cpu.P |= 0x02;
	}
	if (cpu.X & 0x80)
	{
		cpu.P |= 0x80;
	}
	else
	{
		cpu.P &= 0x7F;
	}
}

// done
void InstructionTay()
{
    cpu.Y = cpu.A;
	if (cpu.Y)
	{
		cpu.P &= 0xFD;
	}
	else
	{
		cpu.P |= 0x02;
	}
	if (cpu.Y & 0x80)
	{
		cpu.P |= 0x80;
	}
	else
	{
		cpu.P &= 0x7F;
	}
}

// done
void InstructionTsx()
{
    cpu.X = cpu.S & 0xFF;
	if (cpu.X)
	{
		cpu.P &= 0xFD;
	}
	else
	{
		cpu.P |= 0x02;
	}
	if (cpu.X & 0x80)
	{
		cpu.P |= 0x80;
	}
	else
	{
		cpu.P &= 0x7F;
	}
}

// done
void InstructionTxa()
{
    cpu.A = cpu.X;
	if (cpu.A)
	{
		cpu.P &= 0xFD;
	}
	else
	{
		cpu.P |= 0x02;
	}
	if (cpu.A & 0x80)
	{
		cpu.P |= 0x80;
	}
	else
	{
		cpu.P &= 0x7F;
	}
}

// done
void InstructionTxs()
{
    cpu.S = cpu.X | 0x100;
}

// done
void InstructionTya()
{
    cpu.A = cpu.Y;
	if (cpu.Y)
	{
		cpu.P &= 0xFD;
	}
	else
	{
		cpu.P |= 0x02;
	}
	if (cpu.Y & 0x80)
	{
		cpu.P |= 0x80;
	}
	else
	{
		cpu.P &= 0x7F;
	}
}

// done
void ReadRegister()
{
	_00412204 = _00410C50[_00413A70>>0x13][_00413A70&0x7FFFF];
}

// done
void ReadAddr1()
{
	UINT32 _ADDR1 = *(UINT32 *)(pRam+0x208) & 0xFFFFFF;
	__try
	{
		if ((_ADDR1<FlashEndAdr) && (_ADDR1>=FlashStartAdr))
		{
			_00412204 = ReadFlash(_ADDR1-FlashStartAdr);
		}
		else
		{
			_00412204 = _00410C50[_ADDR1>>0x13][_ADDR1&0x7FFFF];
		}
	}
	__except (EXCEPTION_EXECUTE_HANDLER)
	{
		char ebp_9C[0x80];
		sprintf(ebp_9C, "读无效地址:%06x,可能的原因:字库配置不正确", _ADDR1);
		MessageBox(NULL, ebp_9C, NULL, MB_OK);
		PostQuitMessage(0);
	}
    if ((*(UINT32 *)(pRam+0x207) & 0x01) == 0)
	{
		return;
	}
	pRam[0x208]++;
	if (pRam[0x208] == 0)
	{
		pRam[0x209]++;
		if (pRam[0x209] == 0)
		{
			pRam[0x20A]++;
		}
	}
}

// done
void ReadAddr2()
{
	UINT32 _ADDR2 = *(UINT32 *)(pRam+0x20B) & 0xFFFFFF;
	__try
	{
		if ((_ADDR2<FlashEndAdr) && (_ADDR2>=FlashStartAdr))
		{
			_00412204 = ReadFlash(_ADDR2-FlashStartAdr);
		}
		else
		{
			_00412204 = _00410C50[_ADDR2>>0x13][_ADDR2&0x7FFFF];
		}
	}
	__except (EXCEPTION_EXECUTE_HANDLER)
	{
		char ebp_9C[0x80];
		AbsoluteAddress = BankAddressList[cpu.PC>>0x0C] | (cpu.PC&0x0FFF);
		sprintf(ebp_9C, "读无效地址:%08x\nPC=%04X(%06X)", _ADDR2, cpu.PC, AbsoluteAddress);
		MessageBox(NULL, ebp_9C, NULL, MB_OK);
	}
    if ((*(UINT32 *)(pRam+0x207) & 0x02) == 0)
	{
		return;
	}
	pRam[0x20B]++;
	if (pRam[0x20B] == 0)
	{
		pRam[0x20C]++;
		if (pRam[0x20C] == 0)
		{
			pRam[0x20D]++;
		}
	}
}

// done
void ReadAddr3()
{
	UINT32 _ADDR3 = *(UINT32 *)(pRam+0x20E) & 0xFFFFFF;
	__try
	{
		if ((_ADDR3<FlashEndAdr) && (_ADDR3>=FlashStartAdr))
		{
			_00412204 = ReadFlash(_ADDR3-FlashStartAdr);
		}
		else
		{
			_00412204 = _00410C50[_ADDR3>>0x13][_ADDR3&0x7FFFF];
		}
	}
	__except (EXCEPTION_EXECUTE_HANDLER)
	{
		char ebp_9C[0x80];
		AbsoluteAddress = BankAddressList[cpu.PC>>0x0C] | (cpu.PC&0x0FFF);
		sprintf(ebp_9C, "读无效地址:%08x\nPC=%04X(%06X)", _ADDR3, cpu.PC, AbsoluteAddress);
		MessageBox(NULL, ebp_9C, NULL, MB_OK);
	}
    if ((*(UINT32 *)(pRam+0x207) & 0x04) == 0)
	{
		return;
	}
	pRam[0x20E]++;
	if (pRam[0x20E] == 0)
	{
		pRam[0x20F]++;
		if (pRam[0x20F] == 0)
		{
			pRam[0x210]++;
		}
	}
}

// done
void ReadAddr4()
{
	UINT32 _ADDR4 = *(UINT32 *)(pRam+0x211) & 0xFFFFFF;
	__try
	{
		if ((_ADDR4<FlashEndAdr) && (_ADDR4>=FlashStartAdr))
		{
			_00412204 = ReadFlash(_ADDR4-FlashStartAdr);
		}
		else
		{
			_00412204 = _00410C50[_ADDR4>>0x13][_ADDR4&0x7FFFF];
		}
	}
	__except (EXCEPTION_EXECUTE_HANDLER)
	{
		char ebp_9C[0x80];
		AbsoluteAddress = BankAddressList[cpu.PC>>0x0C] | (cpu.PC&0x0FFF);
		sprintf(ebp_9C, "读无效地址:%08x\nPC=%04X(%06X)", _ADDR4, cpu.PC, AbsoluteAddress);
		MessageBox(NULL, ebp_9C, NULL, MB_OK);
	}
    if ((*(UINT32 *)(pRam+0x207) & 0x08) == 0)
	{
		return;
	}
	pRam[0x211]++;
	if (pRam[0x211] == 0)
	{
		pRam[0x212]++;
		if (pRam[0x212] == 0)
		{
			pRam[0x213]++;
		}
	}
}

// done
void ReadBkSel()
{
    _00412204 = BankSelected;
}

// done
void ReadBkAdrL()
{
    _00412204 = BankAddressList[BankSelected]>>0x0C;
	_00412204 &= 0xFF;
}

// done
void ReadBkAdrH()
{
    _00412204 = BankAddressList[BankSelected]>>0x14;
	_00412204 &= 0xFF;
}

// done
void ReadUrCon1()
{
	_00412204 = _00410C50[_00413A70>>0x13][_00413A70&0x7FFF];
}

// done
void ReadSBuf()
{
    // VOID
}

// done
void WriteRegister()
{
    _00410C50[_00413A70>>0x13][_00413A70&0x7FFF] = _00412204;
}

// done
void WriteAddr1()
{
	UINT32 _ADDR1 = *(UINT32 *)(pRam+0x208) & 0xFFFFFF;
	__try
	{
		if ((_ADDR1<FlashEndAdr) && (_ADDR1>=FlashStartAdr))
		{
			 WriteFlash(_ADDR1-FlashStartAdr, _00412204);
		}
		else
		{
			 _00410C50[_ADDR1>>0x13][_ADDR1&0x7FFFF] = _00412204;
		}
	}
	__except (EXCEPTION_EXECUTE_HANDLER)
	{
		char ebp_9C[0x80];
		AbsoluteAddress = BankAddressList[cpu.PC>>0x0C] | (cpu.PC&0x0FFF);
		sprintf(ebp_9C, "写无效地址:%08x\nPC=%04X(%06X)", _ADDR1, cpu.PC, AbsoluteAddress);
		MessageBox(NULL, ebp_9C, NULL, MB_OK);
	}
    if ((*(UINT32 *)(pRam+0x207) & 0x01) == 0)
	{
		return;
	}
	pRam[0x208]++;
	if (pRam[0x208] == 0)
	{
		pRam[0x209]++;
		if (pRam[0x209] == 0)
		{
			pRam[0x20A]++;
		}
	}
}

// done
void WriteAddr2()
{
	UINT32 _ADDR2 = *(UINT32 *)(pRam+0x20B) & 0xFFFFFF;
	__try
	{
		if ((_ADDR2<FlashEndAdr) && (_ADDR2>=FlashStartAdr))
		{
			 WriteFlash(_ADDR2-FlashStartAdr, _00412204);
		}
		else
		{
			 _00410C50[_ADDR2>>0x13][_ADDR2&0x7FFFF] = _00412204;
		}
	}
	__except (EXCEPTION_EXECUTE_HANDLER)
	{
		char ebp_9C[0x80];
		AbsoluteAddress = BankAddressList[cpu.PC>>0x0C] | (cpu.PC&0x0FFF);
		sprintf(ebp_9C, "写无效地址:%08x\nPC=%04X(%06X)", _ADDR2, cpu.PC, AbsoluteAddress);
		MessageBox(NULL, ebp_9C, NULL, MB_OK);
	}
    if ((*(UINT32 *)(pRam+0x207) & 0x02) == 0)
	{
		return;
	}
	pRam[0x20B]++;
	if (pRam[0x20B] == 0)
	{
		pRam[0x20C]++;
		if (pRam[0x20C] == 0)
		{
			pRam[0x20D]++;
		}
	}
}

// done
void WriteAddr3()
{
	UINT32 _ADDR3 = *(UINT32 *)(pRam+0x20E) & 0xFFFFFF;
	__try
	{
		if ((_ADDR3<FlashEndAdr) && (_ADDR3>=FlashStartAdr))
		{
			 WriteFlash(_ADDR3-FlashStartAdr, _00412204);
		}
		else
		{
			 _00410C50[_ADDR3>>0x13][_ADDR3&0x7FFFF] = _00412204;
		}
	}
	__except (EXCEPTION_EXECUTE_HANDLER)
	{
		char ebp_9C[0x80];
		AbsoluteAddress = BankAddressList[cpu.PC>>0x0C] | (cpu.PC&0x0FFF);
		sprintf(ebp_9C, "写无效地址:%08x\nPC=%04X(%06X)", _ADDR3, cpu.PC, AbsoluteAddress);
		MessageBox(NULL, ebp_9C, NULL, MB_OK);
	}
    if ((*(UINT32 *)(pRam+0x207) & 0x04) == 0)
	{
		return;
	}
	pRam[0x20E]++;
	if (pRam[0x20E] == 0)
	{
		pRam[0x20F]++;
		if (pRam[0x20F] == 0)
		{
			pRam[0x210]++;
		}
	}
}

// done
void WriteAddr4()
{
	UINT32 _ADDR4 = *(UINT32 *)(pRam+0x211) & 0xFFFFFF;
	__try
	{
		if ((_ADDR4<FlashEndAdr) && (_ADDR4>=FlashStartAdr))
		{
			 WriteFlash(_ADDR4-FlashStartAdr, _00412204);
		}
		else
		{
			 _00410C50[_ADDR4>>0x13][_ADDR4&0x7FFFF] = _00412204;
		}
	}
	__except (EXCEPTION_EXECUTE_HANDLER)
	{
		char ebp_9C[0x80];
		AbsoluteAddress = BankAddressList[cpu.PC>>0x0C] | (cpu.PC&0x0FFF);
		sprintf(ebp_9C, "写无效地址:%08x\nPC=%04X(%06X)", _ADDR4, cpu.PC, AbsoluteAddress);
		MessageBox(NULL, ebp_9C, NULL, MB_OK);
	}
    if ((*(UINT32 *)(pRam+0x207) & 0x08) == 0)
	{
		return;
	}
	pRam[0x211]++;
	if (pRam[0x211] == 0)
	{
		pRam[0x212]++;
		if (pRam[0x212] == 0)
		{
			pRam[0x213]++;
		}
	}
}

// done
void WriteBkSel()
{
    BankSelected = _00412204;
}

// done
void WriteBkAdrL()
{
	_00412204 &= 0xFF;
	BankAddressList[BankSelected] &= 0xFF00000;
	BankAddressList[BankSelected] |= _00412204 << 0x0C;
}

// done
void WriteBkAdrH()
{
	_00412204 &= 0xFF;
	if (_00412204>0x0F)
	{
		_00412204 &= 0x0F;
	}
	BankAddressList[BankSelected] &= 0xFF000;
	BankAddressList[BankSelected] |= _00412204 << 0x14;
}

// done
void WriteIsr()
{
    pRam[_00413A70] &= _00412204;
}

// done
void WriteTIsr()
{
    pRam[_00413A70] &= _00412204;
}

// done
void WriteSysCon()
{
    if (_00412204&0x08)
	{
		SleepFlag = 1;
	}
	_00410C50[_00413A70>>0x13][_00413A70&0x7FFFF] = _00412204;
}

// done
void WriteUsCon1()
{
    WriteRegister();
}

// done
void WriteSBuf()
{
    // VOID
}

void NoInterruption()
{
    // VOID
}

// done
void _00408EE0(UINT32 address, void (*func)())
{
    _004115FC[address] = func;
}

// done
void _00408EF2(UINT32 address, void (*func)())
{
    _00412E70[address] = func;
}

// 操作码和寄存器功能映射
void _00408F04()
{
    pInterruptHandle[0] = NoInterruption;
    pInterruptHandle[1] = InterruptHandle;
    _00412268 = _0040BA60;
    _0041226C = _0040BA38;

	// BRK
	_00412A70[0x00] = 0x07;
	_00412270[0x00] = InstructionUnknown;
	_00412670[0x00] = AddressingModeNop;
	// ORA - (Indirect,X)
	_00412A70[0x01] = 0x06;
	_00412270[0x01] = InstructionOra;
	_00412670[0x01] = AddressingModeIndirectX;
	// Future Expansion
	_00412A70[0x02] = 0x02;
	_00412270[0x02] = InstructionUnknown;
	_00412670[0x02] = AddressingModeNop;
	// Future Expansion
	_00412A70[0x03] = 0x02;
	_00412270[0x03] = InstructionUnknown;
	_00412670[0x03] = AddressingModeNop;
	// Future Expansion
	_00412A70[0x04] = 0x03;
	_00412270[0x04] = InstructionUnknown;
	_00412670[0x04] = AddressingModeNop;
	// ORA - Zero Page
	_00412A70[0x05] = 0x03;
	_00412270[0x05] = InstructionOra;
	_00412670[0x05] = AddressingModeZeroPage;
	// ASL - Zero Page
	_00412A70[0x06] = 0x05;
	_00412270[0x06] = InstructionAsl;
	_00412670[0x06] = AddressingModeZeroPage;
	// Future Expansion
	_00412A70[0x07] = 0x02;
	_00412270[0x07] = InstructionUnknown;
	_00412670[0x07] = AddressingModeNop;
	// PHP
	_00412A70[0x08] = 0x03;
	_00412270[0x08] = InstructionPhp;
	_00412670[0x08] = AddressingModeNop;
	// ORA - Immediate
	_00412A70[0x09] = 0x03;
	_00412270[0x09] = InstructionOra;
	_00412670[0x09] = AddressingModeImmediate;
	// ASL - Accumulator
	_00412A70[0x0A] = 0x02;
	_00412270[0x0A] = InstructionAsl_A;
	_00412670[0x0A] = AddressingModeNop;
	// Future Expansion
	_00412A70[0x0B] = 0x02;
	_00412270[0x0B] = InstructionUnknown;
	_00412670[0x0B] = AddressingModeNop;
	// Future Expansion
	_00412A70[0x0C] = 0x04;
	_00412270[0x0C] = InstructionUnknown;
	_00412670[0x0C] = AddressingModeNop;
	// ORA - Absolute
	_00412A70[0x0D] = 0x04;
	_00412270[0x0D] = InstructionOra;
	_00412670[0x0D] = AddressingModeAbsolute;
	// ASL - Absolute
	_00412A70[0x0E] = 0x06;
	_00412270[0x0E] = InstructionAsl;
	_00412670[0x0E] = AddressingModeAbsolute;
	// BBR0
	_00412A70[0x0F] = 0x02;
	_00412270[0x0F] = InstructionBbr0;
	_00412670[0x0F] = AddressingModeNone;
	// BPL
	_00412A70[0x10] = 0x02;
	_00412270[0x10] = InstructionBpl;
	_00412670[0x10] = AddressingModeNone;
	// ORA - (Indirect),Y
	_00412A70[0x11] = 0x05;
	_00412270[0x11] = InstructionOra;
	_00412670[0x11] = AddressingModeIndirectY;
	// Future Expansion
	_00412A70[0x12] = 0x03;
	_00412270[0x12] = InstructionUnknown;
	_00412670[0x12] = AddressingModeNop;
	// Future Expansion
	_00412A70[0x13] = 0x02;
	_00412270[0x13] = InstructionUnknown;
	_00412670[0x13] = AddressingModeNop;
	// Future Expansion
	_00412A70[0x14] = 0x03;
	_00412270[0x14] = InstructionUnknown;
	_00412670[0x14] = AddressingModeNop;
	// ORA - Zero Page,X
	_00412A70[0x15] = 0x04;
	_00412270[0x15] = InstructionOra;
	_00412670[0x15] = AddressingModeZeroPageX;
	// ASL - Zero Page,X
	_00412A70[0x16] = 0x06;
	_00412270[0x16] = InstructionAsl;
	_00412670[0x16] = AddressingModeZeroPageX;
	// Future Expansion
	_00412A70[0x17] = 0x02;
	_00412270[0x17] = InstructionUnknown;
	_00412670[0x17] = AddressingModeNop;
	// CLC
	_00412A70[0x18] = 0x02;
	_00412270[0x18] = InstructionClc;
	_00412670[0x18] = AddressingModeNop;
	// ORA - Absolute,Y
	_00412A70[0x19] = 0x04;
	_00412270[0x19] = InstructionOra;
	_00412670[0x19] = AddressingModeAbsoluteY;
	// INC - Accumulator
	_00412A70[0x1A] = 0x02;
	_00412270[0x1A] = InstructionInc_A;
	_00412670[0x1A] = AddressingModeNop;
	// Future Expansion
	_00412A70[0x1B] = 0x02;
	_00412270[0x1B] = InstructionUnknown;
	_00412670[0x1B] = AddressingModeNop;
	// Future Expansion
	_00412A70[0x1C] = 0x04;
	_00412270[0x1C] = InstructionUnknown;
	_00412670[0x1C] = AddressingModeNop;
	// ORA - Absolute,X
	_00412A70[0x1D] = 0x04;
	_00412270[0x1D] = InstructionOra;
	_00412670[0x1D] = AddressingModeAbsoluteX;
	// ASL - Absolute,X
	_00412A70[0x1E] = 0x07;
	_00412270[0x1E] = InstructionAsl;
	_00412670[0x1E] = AddressingModeAbsoluteX;
	// BBR1
	_00412A70[0x1F] = 0x02;
	_00412270[0x1F] = InstructionBbr1;
	_00412670[0x1F] = AddressingModeNone;
	// JSR
	_00412A70[0x20] = 0x06;
	_00412270[0x20] = InstructionJsr;
	_00412670[0x20] = AddressingModeAbsolute;
	// AND - (Indirect,X)
	_00412A70[0x21] = 0x06;
	_00412270[0x21] = InstructionAnd;
	_00412670[0x21] = AddressingModeIndirectX;
	// Future Expansion
	_00412A70[0x22] = 0x02;
	_00412270[0x22] = InstructionUnknown;
	_00412670[0x22] = AddressingModeNop;
	// Future Expansion
	_00412A70[0x23] = 0x02;
	_00412270[0x23] = InstructionUnknown;
	_00412670[0x23] = AddressingModeNop;
	// BIT - Zero Page
	_00412A70[0x24] = 0x03;
	_00412270[0x24] = InstructionBit;
	_00412670[0x24] = AddressingModeZeroPage;
	// AND - Zero Page
	_00412A70[0x25] = 0x03;
	_00412270[0x25] = InstructionAnd;
	_00412670[0x25] = AddressingModeZeroPage;
	// ROL - Zero Page
	_00412A70[0x26] = 0x05;
	_00412270[0x26] = InstructionRol;
	_00412670[0x26] = AddressingModeZeroPage;
	// Future Expansion
	_00412A70[0x27] = 0x02;
	_00412270[0x27] = InstructionUnknown;
	_00412670[0x27] = AddressingModeNop;
	// PLP
	_00412A70[0x28] = 0x04;
	_00412270[0x28] = InstructionPlp;
	_00412670[0x28] = AddressingModeNop;
	// AND - Immediate
	_00412A70[0x29] = 0x03;
	_00412270[0x29] = InstructionAnd;
	_00412670[0x29] = AddressingModeImmediate;
	// ROL - Accumulator
	_00412A70[0x2A] = 0x02;
	_00412270[0x2A] = InstructionRol_A;
	_00412670[0x2A] = AddressingModeNop;
	// Future Expansion
	_00412A70[0x2B] = 0x02;
	_00412270[0x2B] = InstructionUnknown;
	_00412670[0x2B] = AddressingModeNop;
	// BIT - Absolute
	_00412A70[0x2C] = 0x04;
	_00412270[0x2C] = InstructionBit;
	_00412670[0x2C] = AddressingModeAbsolute;
	// AND - Absolute
	_00412A70[0x2D] = 0x04;
	_00412270[0x2D] = InstructionAnd;
	_00412670[0x2D] = AddressingModeAbsolute;
	// ROL - Absolute
	_00412A70[0x2E] = 0x06;
	_00412270[0x2E] = InstructionRol;
	_00412670[0x2E] = AddressingModeAbsolute;
	// BBR2
	_00412A70[0x2F] = 0x02;
	_00412270[0x2F] = InstructionBbr2;
	_00412670[0x2F] = AddressingModeNone;
	// BMI
	_00412A70[0x30] = 0x02;
	_00412270[0x30] = InstructionBmi;
	_00412670[0x30] = AddressingModeNone;
	// AND - (Indirect),Y
	_00412A70[0x31] = 0x05;
	_00412270[0x31] = InstructionAnd;
	_00412670[0x31] = AddressingModeIndirectY;
	// Future Expansion
	_00412A70[0x32] = 0x03;
	_00412270[0x32] = InstructionUnknown;
	_00412670[0x32] = AddressingModeNop;
	// Future Expansion
	_00412A70[0x33] = 0x02;
	_00412270[0x33] = InstructionUnknown;
	_00412670[0x33] = AddressingModeNop;
	// BIT - Zero Page,X
	_00412A70[0x34] = 0x04;
	_00412270[0x34] = InstructionBit;
	_00412670[0x34] = AddressingModeZeroPageX;
	// AND - Zero Page,X
	_00412A70[0x35] = 0x04;
	_00412270[0x35] = InstructionAnd;
	_00412670[0x35] = AddressingModeZeroPageX;
	// ROL - Zero Page,X
	_00412A70[0x36] = 0x06;
	_00412270[0x36] = InstructionRol;
	_00412670[0x36] = AddressingModeZeroPageX;
	// Future Expansion
	_00412A70[0x37] = 0x02;
	_00412270[0x37] = InstructionUnknown;
	_00412670[0x37] = AddressingModeNop;
	// SEC
	_00412A70[0x38] = 0x02;
	_00412270[0x38] = InstructionSec;
	_00412670[0x38] = AddressingModeNop;
	// AND - Absolute,Y
	_00412A70[0x39] = 0x04;
	_00412270[0x39] = InstructionAnd;
	_00412670[0x39] = AddressingModeAbsoluteY;
	// DEC - Accumulator
	_00412A70[0x3A] = 0x02;
	_00412270[0x3A] = InstructionDec_A;
	_00412670[0x3A] = AddressingModeNop;
	// Future Expansion
	_00412A70[0x3B] = 0x02;
	_00412270[0x3B] = InstructionUnknown;
	_00412670[0x3B] = AddressingModeNop;
	// BIT - Absolute,X
	_00412A70[0x3C] = 0x04;
	_00412270[0x3C] = InstructionBit;
	_00412670[0x3C] = AddressingModeAbsoluteX;
	// AND - Absolute,X
	_00412A70[0x3D] = 0x04;
	_00412270[0x3D] = InstructionAnd;
	_00412670[0x3D] = AddressingModeAbsoluteX;
	// ROL - Absolute,X
	_00412A70[0x3E] = 0x07;
	_00412270[0x3E] = InstructionRol;
	_00412670[0x3E] = AddressingModeAbsoluteX;
	// BBR3
	_00412A70[0x3F] = 0x02;
	_00412270[0x3F] = InstructionBbr3;
	_00412670[0x3F] = AddressingModeNone;
	// RTI
	_00412A70[0x40] = 0x06;
	_00412270[0x40] = InstructionRti;
	_00412670[0x40] = AddressingModeNop;
	// EOR - (Indirect,X)
	_00412A70[0x41] = 0x06;
	_00412270[0x41] = InstructionEor;
	_00412670[0x41] = AddressingModeIndirectX;
	// Future Expansion
	_00412A70[0x42] = 0x02;
	_00412270[0x42] = InstructionUnknown;
	_00412670[0x42] = AddressingModeNop;
	// Future Expansion
	_00412A70[0x43] = 0x02;
	_00412270[0x43] = InstructionUnknown;
	_00412670[0x43] = AddressingModeNop;
	// Future Expansion
	_00412A70[0x44] = 0x02;
	_00412270[0x44] = InstructionUnknown;
	_00412670[0x44] = AddressingModeNop;
	// EOR - Zero Page
	_00412A70[0x45] = 0x03;
	_00412270[0x45] = InstructionEor;
	_00412670[0x45] = AddressingModeZeroPage;
	// LSR - Zero Page
	_00412A70[0x46] = 0x05;
	_00412270[0x46] = InstructionLsr;
	_00412670[0x46] = AddressingModeZeroPage;
	// Future Expansion
	_00412A70[0x47] = 0x02;
	_00412270[0x47] = InstructionUnknown;
	_00412670[0x47] = AddressingModeNop;
	// PHA
	_00412A70[0x48] = 0x03;
	_00412270[0x48] = InstructionPha;
	_00412670[0x48] = AddressingModeNop;
	// EOR - Immediate
	_00412A70[0x49] = 0x03;
	_00412270[0x49] = InstructionEor;
	_00412670[0x49] = AddressingModeImmediate;
	// LSR - Accumulator
	_00412A70[0x4A] = 0x02;
	_00412270[0x4A] = InstructionLsr_A;
	_00412670[0x4A] = AddressingModeNop;
	// Future Expansion
	_00412A70[0x4B] = 0x02;
	_00412270[0x4B] = InstructionUnknown;
	_00412670[0x4B] = AddressingModeNop;
	// JMP - Absolute
	_00412A70[0x4C] = 0x03;
	_00412270[0x4C] = InstructionJmp;
	_00412670[0x4C] = AddressingModeAbsolute;
	// EOR - Absolute
	_00412A70[0x4D] = 0x04;
	_00412270[0x4D] = InstructionEor;
	_00412670[0x4D] = AddressingModeAbsolute;
	// LSR - Absolute
	_00412A70[0x4E] = 0x06;
	_00412270[0x4E] = InstructionLsr;
	_00412670[0x4E] = AddressingModeAbsolute;
	// BBR4
	_00412A70[0x4F] = 0x02;
	_00412270[0x4F] = InstructionBbr4;
	_00412670[0x4F] = AddressingModeNone;
	// BVC
	_00412A70[0x50] = 0x02;
	_00412270[0x50] = InstructionBvc;
	_00412670[0x50] = AddressingModeNone;
	// EOR - (Indirect),Y
	_00412A70[0x51] = 0x05;
	_00412270[0x51] = InstructionEor;
	_00412670[0x51] = AddressingModeIndirectY;
	// Future Expansion
	_00412A70[0x52] = 0x03;
	_00412270[0x52] = InstructionUnknown;
	_00412670[0x52] = AddressingModeNop;
	// Future Expansion
	_00412A70[0x53] = 0x02;
	_00412270[0x53] = InstructionUnknown;
	_00412670[0x53] = AddressingModeNop;
	// Future Expansion
	_00412A70[0x54] = 0x02;
	_00412270[0x54] = InstructionUnknown;
	_00412670[0x54] = AddressingModeNop;
	// EOR - Zero Page,X
	_00412A70[0x55] = 0x04;
	_00412270[0x55] = InstructionEor;
	_00412670[0x55] = AddressingModeZeroPageX;
	// LSR - Zero Page,X
	_00412A70[0x56] = 0x06;
	_00412270[0x56] = InstructionLsr;
	_00412670[0x56] = AddressingModeZeroPageX;
	// Future Expansion
	_00412A70[0x57] = 0x02;
	_00412270[0x57] = InstructionUnknown;
	_00412670[0x57] = AddressingModeNop;
	// CLI
	_00412A70[0x58] = 0x02;
	_00412270[0x58] = InstructionCli;
	_00412670[0x58] = AddressingModeNop;
	// EOR - Absolute,Y
	_00412A70[0x59] = 0x04;
	_00412270[0x59] = InstructionEor;
	_00412670[0x59] = AddressingModeAbsoluteY;
	// PHY
	_00412A70[0x5A] = 0x03;
	_00412270[0x5A] = InstructionPhy;
	_00412670[0x5A] = AddressingModeNop;
	// Future Expansion
	_00412A70[0x5B] = 0x02;
	_00412270[0x5B] = InstructionUnknown;
	_00412670[0x5B] = AddressingModeNop;
	// Future Expansion
	_00412A70[0x5C] = 0x02;
	_00412270[0x5C] = InstructionUnknown;
	_00412670[0x5C] = AddressingModeNop;
	// EOR - Absolute,X
	_00412A70[0x5D] = 0x04;
	_00412270[0x5D] = InstructionEor;
	_00412670[0x5D] = AddressingModeAbsoluteX;
	// LSR - Absolute,X
	_00412A70[0x5E] = 0x07;
	_00412270[0x5E] = InstructionLsr;
	_00412670[0x5E] = AddressingModeAbsoluteX;
	// BBR5
	_00412A70[0x5F] = 0x02;
	_00412270[0x5F] = InstructionBbr5;
	_00412670[0x5F] = AddressingModeNone;
	// RTS
	_00412A70[0x60] = 0x06;
	_00412270[0x60] = InstructionRts;
	_00412670[0x60] = AddressingModeNop;
	// ADC - (Indirect,X)
	_00412A70[0x61] = 0x06;
	_00412270[0x61] = InstructionAdc;
	_00412670[0x61] = AddressingModeIndirectX;
	// Future Expansion
	_00412A70[0x62] = 0x02;
	_00412270[0x62] = InstructionUnknown;
	_00412670[0x62] = AddressingModeNop;
	// Future Expansion
	_00412A70[0x63] = 0x02;
	_00412270[0x63] = InstructionUnknown;
	_00412670[0x63] = AddressingModeNop;
	// STZ - Zero Page
	_00412A70[0x64] = 0x03;
	_00412270[0x64] = InstructionStz;
	_00412670[0x64] = AddressingModeZeroPage;
	// ADC - Zero Page
	_00412A70[0x65] = 0x03;
	_00412270[0x65] = InstructionAdc;
	_00412670[0x65] = AddressingModeZeroPage;
	// ROR - Zero Page
	_00412A70[0x66] = 0x05;
	_00412270[0x66] = InstructionRor;
	_00412670[0x66] = AddressingModeZeroPage;
	// Future Expansion
	_00412A70[0x67] = 0x02;
	_00412270[0x67] = InstructionUnknown;
	_00412670[0x67] = AddressingModeNop;
	// PLA
	_00412A70[0x68] = 0x04;
	_00412270[0x68] = InstructionPla;
	_00412670[0x68] = AddressingModeNop;
	// ADC - Immediate
	_00412A70[0x69] = 0x03;
	_00412270[0x69] = InstructionAdc;
	_00412670[0x69] = AddressingModeImmediate;
	// ROR - Accumulator
	_00412A70[0x6A] = 0x02;
	_00412270[0x6A] = InstructionRor_A;
	_00412670[0x6A] = AddressingModeNop;
	// Future Expansion
	_00412A70[0x6B] = 0x02;
	_00412270[0x6B] = InstructionUnknown;
	_00412670[0x6B] = AddressingModeNop;
	// JMP - Indirect
	_00412A70[0x6C] = 0x05;
	_00412270[0x6C] = InstructionJmp;
	_00412670[0x6C] = AddressingModeIndirect;
	// ADC - Absolute
	_00412A70[0x6D] = 0x04;
	_00412270[0x6D] = InstructionAdc;
	_00412670[0x6D] = AddressingModeAbsolute;
	// ROR - Absolute
	_00412A70[0x6E] = 0x06;
	_00412270[0x6E] = InstructionRor;
	_00412670[0x6E] = AddressingModeAbsolute;
	// BBR6
	_00412A70[0x6F] = 0x02;
	_00412270[0x6F] = InstructionBbr6;
	_00412670[0x6F] = AddressingModeNone;
	// BVS
	_00412A70[0x70] = 0x02;
	_00412270[0x70] = InstructionBvs;
	_00412670[0x70] = AddressingModeNone;
	// ADC - (Indirect),Y
	_00412A70[0x71] = 0x05;
	_00412270[0x71] = InstructionAdc;
	_00412670[0x71] = AddressingModeIndirectY;
	// Future Expansion
	_00412A70[0x72] = 0x03;
	_00412270[0x72] = InstructionUnknown;
	_00412670[0x72] = AddressingModeNop;
	// Future Expansion
	_00412A70[0x73] = 0x02;
	_00412270[0x73] = InstructionUnknown;
	_00412670[0x73] = AddressingModeNop;
	// STZ - Zero Page,X
	_00412A70[0x74] = 0x04;
	_00412270[0x74] = InstructionStz;
	_00412670[0x74] = AddressingModeZeroPageX;
	// ADC - Zero Page,X
	_00412A70[0x75] = 0x04;
	_00412270[0x75] = InstructionAdc;
	_00412670[0x75] = AddressingModeZeroPageX;
	// ROR - Zero Page,X
	_00412A70[0x76] = 0x06;
	_00412270[0x76] = InstructionRor;
	_00412670[0x76] = AddressingModeZeroPageX;
	// Future Expansion
	_00412A70[0x77] = 0x02;
	_00412270[0x77] = InstructionUnknown;
	_00412670[0x77] = AddressingModeNop;
	// SEI
	_00412A70[0x78] = 0x02;
	_00412270[0x78] = InstructionSei;
	_00412670[0x78] = AddressingModeNop;
	// ADC - Absolute,Y
	_00412A70[0x79] = 0x04;
	_00412270[0x79] = InstructionAdc;
	_00412670[0x79] = AddressingModeAbsoluteY;
	// PLY
	_00412A70[0x7A] = 0x04;
	_00412270[0x7A] = InstructionPly;
	_00412670[0x7A] = AddressingModeNop;
	// Future Expansion
	_00412A70[0x7B] = 0x02;
	_00412270[0x7B] = InstructionUnknown;
	_00412670[0x7B] = AddressingModeNop;
	// Future Expansion
	_00412A70[0x7C] = 0x06;
	_00412270[0x7C] = InstructionUnknown;
	_00412670[0x7C] = AddressingModeNop;
	// ADC - Absolute,X
	_00412A70[0x7D] = 0x04;
	_00412270[0x7D] = InstructionAdc;
	_00412670[0x7D] = AddressingModeAbsoluteX;
	// ROR - Absolute,X
	_00412A70[0x7E] = 0x07;
	_00412270[0x7E] = InstructionRor;
	_00412670[0x7E] = AddressingModeAbsoluteX;
	// BBR7
	_00412A70[0x7F] = 0x02;
	_00412270[0x7F] = InstructionBbr7;
	_00412670[0x7F] = AddressingModeNone;
	// BRA
	_00412A70[0x80] = 0x03;
	_00412270[0x80] = InstructionBra;
	_00412670[0x80] = AddressingModeNone;
	// STA - (Indirect,X)
	_00412A70[0x81] = 0x06;
	_00412270[0x81] = InstructionSta;
	_00412670[0x81] = AddressingModeIndirectX;
	// Future Expansion
	_00412A70[0x82] = 0x02;
	_00412270[0x82] = InstructionUnknown;
	_00412670[0x82] = AddressingModeNop;
	// Future Expansion
	_00412A70[0x83] = 0x02;
	_00412270[0x83] = InstructionUnknown;
	_00412670[0x83] = AddressingModeNop;
	// STY - Zero Page
	_00412A70[0x84] = 0x02;
	_00412270[0x84] = InstructionSty;
	_00412670[0x84] = AddressingModeZeroPage;
	// STA - Zero Page
	_00412A70[0x85] = 0x02;
	_00412270[0x85] = InstructionSta;
	_00412670[0x85] = AddressingModeZeroPage;
	// STX - Zero Page
	_00412A70[0x86] = 0x02;
	_00412270[0x86] = InstructionStx;
	_00412670[0x86] = AddressingModeZeroPage;
	// Future Expansion
	_00412A70[0x87] = 0x02;
	_00412270[0x87] = InstructionUnknown;
	_00412670[0x87] = AddressingModeNop;
	// DEY
	_00412A70[0x88] = 0x02;
	_00412270[0x88] = InstructionDey;
	_00412670[0x88] = AddressingModeNop;
	// BIT - Immediate
	_00412A70[0x89] = 0x02;
	_00412270[0x89] = InstructionBit;
	_00412670[0x89] = AddressingModeImmediate;
	// TXA
	_00412A70[0x8A] = 0x02;
	_00412270[0x8A] = InstructionTxa;
	_00412670[0x8A] = AddressingModeNop;
	// Future Expansion
	_00412A70[0x8B] = 0x02;
	_00412270[0x8B] = InstructionUnknown;
	_00412670[0x8B] = AddressingModeNop;
	// STY - Absolute
	_00412A70[0x8C] = 0x04;
	_00412270[0x8C] = InstructionSty;
	_00412670[0x8C] = AddressingModeAbsolute;
	// STA - Absolute
	_00412A70[0x8D] = 0x04;
	_00412270[0x8D] = InstructionSta;
	_00412670[0x8D] = AddressingModeAbsolute;
	// STX - Absolute
	_00412A70[0x8E] = 0x04;
	_00412270[0x8E] = InstructionStx;
	_00412670[0x8E] = AddressingModeAbsolute;
	// BBS0
	_00412A70[0x8F] = 0x02;
	_00412270[0x8F] = InstructionBbs0;
	_00412670[0x8F] = AddressingModeNone;
	// BCC
	_00412A70[0x90] = 0x02;
	_00412270[0x90] = InstructionBcc;
	_00412670[0x90] = AddressingModeNone;
	// STA - (Indirect),Y
	_00412A70[0x91] = 0x06;
	_00412270[0x91] = InstructionSta;
	_00412670[0x91] = AddressingModeIndirectY;
	// Future Expansion
	_00412A70[0x92] = 0x03;
	_00412270[0x92] = InstructionUnknown;
	_00412670[0x92] = AddressingModeNop;
	// Future Expansion
	_00412A70[0x93] = 0x02;
	_00412270[0x93] = InstructionUnknown;
	_00412670[0x93] = AddressingModeNop;
	// STY - Zero Page,X
	_00412A70[0x94] = 0x04;
	_00412270[0x94] = InstructionSty;
	_00412670[0x94] = AddressingModeZeroPageX;
	// STA - Zero Page,X
	_00412A70[0x95] = 0x04;
	_00412270[0x95] = InstructionSta;
	_00412670[0x95] = AddressingModeZeroPageX;
	// STX - Zero Page,Y
	_00412A70[0x96] = 0x04;
	_00412270[0x96] = InstructionStx;
	_00412670[0x96] = AddressingModeZeroPageY;
	// Future Expansion
	_00412A70[0x97] = 0x02;
	_00412270[0x97] = InstructionUnknown;
	_00412670[0x97] = AddressingModeNop;
	// TYA
	_00412A70[0x98] = 0x02;
	_00412270[0x98] = InstructionTya;
	_00412670[0x98] = AddressingModeNop;
	// STA - Absolute,Y
	_00412A70[0x99] = 0x05;
	_00412270[0x99] = InstructionSta;
	_00412670[0x99] = AddressingModeAbsoluteY;
	// TXS
	_00412A70[0x9A] = 0x02;
	_00412270[0x9A] = InstructionTxs;
	_00412670[0x9A] = AddressingModeNop;
	// Future Expansion
	_00412A70[0x9B] = 0x02;
	_00412270[0x9B] = InstructionUnknown;
	_00412670[0x9B] = AddressingModeNop;
	// STZ - Absolute
	_00412A70[0x9C] = 0x04;
	_00412270[0x9C] = InstructionStz;
	_00412670[0x9C] = AddressingModeAbsolute;
	// STA - Absolute,X
	_00412A70[0x9D] = 0x05;
	_00412270[0x9D] = InstructionSta;
	_00412670[0x9D] = AddressingModeAbsoluteX;
	// STZ - Absolute,X
	_00412A70[0x9E] = 0x05;
	_00412270[0x9E] = InstructionStz;
	_00412670[0x9E] = AddressingModeAbsoluteX;
	// BBS1
	_00412A70[0x9F] = 0x02;
	_00412270[0x9F] = InstructionBbs1;
	_00412670[0x9F] = AddressingModeNone;
	// LDY - Immediate
	_00412A70[0xA0] = 0x03;
	_00412270[0xA0] = InstructionLdy;
	_00412670[0xA0] = AddressingModeImmediate;
	// LDA - (Indirect,X)
	_00412A70[0xA1] = 0x06;
	_00412270[0xA1] = InstructionLda;
	_00412670[0xA1] = AddressingModeIndirectX;
	// LDX - Immediate
	_00412A70[0xA2] = 0x03;
	_00412270[0xA2] = InstructionLdx;
	_00412670[0xA2] = AddressingModeImmediate;
	// Future Expansion
	_00412A70[0xA3] = 0x02;
	_00412270[0xA3] = InstructionUnknown;
	_00412670[0xA3] = AddressingModeNop;
	// LDY - Zero Page
	_00412A70[0xA4] = 0x03;
	_00412270[0xA4] = InstructionLdy;
	_00412670[0xA4] = AddressingModeZeroPage;
	// LDA - Zero Page
	_00412A70[0xA5] = 0x03;
	_00412270[0xA5] = InstructionLda;
	_00412670[0xA5] = AddressingModeZeroPage;
	// LDX - Zero Page
	_00412A70[0xA6] = 0x03;
	_00412270[0xA6] = InstructionLdx;
	_00412670[0xA6] = AddressingModeZeroPage;
	// Future Expansion
	_00412A70[0xA7] = 0x02;
	_00412270[0xA7] = InstructionUnknown;
	_00412670[0xA7] = AddressingModeNop;
	// TAY
	_00412A70[0xA8] = 0x02;
	_00412270[0xA8] = InstructionTay;
	_00412670[0xA8] = AddressingModeNop;
	// LDA - Immediate
	_00412A70[0xA9] = 0x03;
	_00412270[0xA9] = InstructionLda;
	_00412670[0xA9] = AddressingModeImmediate;
	// TAX
	_00412A70[0xAA] = 0x02;
	_00412270[0xAA] = InstructionTax;
	_00412670[0xAA] = AddressingModeNop;
	// Future Expansion
	_00412A70[0xAB] = 0x02;
	_00412270[0xAB] = InstructionUnknown;
	_00412670[0xAB] = AddressingModeNop;
	// LDY - Absolute
	_00412A70[0xAC] = 0x04;
	_00412270[0xAC] = InstructionLdy;
	_00412670[0xAC] = AddressingModeAbsolute;
	// LDA - Absolute
	_00412A70[0xAD] = 0x04;
	_00412270[0xAD] = InstructionLda;
	_00412670[0xAD] = AddressingModeAbsolute;
	// LDX - Absolute
	_00412A70[0xAE] = 0x04;
	_00412270[0xAE] = InstructionLdx;
	_00412670[0xAE] = AddressingModeAbsolute;
	// BBS2
	_00412A70[0xAF] = 0x02;
	_00412270[0xAF] = InstructionBbs2;
	_00412670[0xAF] = AddressingModeNone;
	// BCS
	_00412A70[0xB0] = 0x02;
	_00412270[0xB0] = InstructionBcs;
	_00412670[0xB0] = AddressingModeNone;
	// LDA - (Indirect),Y
	_00412A70[0xB1] = 0x05;
	_00412270[0xB1] = InstructionLda;
	_00412670[0xB1] = AddressingModeIndirectY;
	// Future Expansion
	_00412A70[0xB2] = 0x03;
	_00412270[0xB2] = InstructionUnknown;
	_00412670[0xB2] = AddressingModeNop;
	// Future Expansion
	_00412A70[0xB3] = 0x02;
	_00412270[0xB3] = InstructionUnknown;
	_00412670[0xB3] = AddressingModeNop;
	// LDY - Zero Page,X
	_00412A70[0xB4] = 0x04;
	_00412270[0xB4] = InstructionLdy;
	_00412670[0xB4] = AddressingModeZeroPageX;
	// LDA - Zero Page,X
	_00412A70[0xB5] = 0x04;
	_00412270[0xB5] = InstructionLda;
	_00412670[0xB5] = AddressingModeZeroPageX;
	// LDX - Zero Page,Y
	_00412A70[0xB6] = 0x04;
	_00412270[0xB6] = InstructionLdx;
	_00412670[0xB6] = AddressingModeZeroPageY;
	// Future Expansion
	_00412A70[0xB7] = 0x02;
	_00412270[0xB7] = InstructionUnknown;
	_00412670[0xB7] = AddressingModeNop;
	// CLV
	_00412A70[0xB8] = 0x02;
	_00412270[0xB8] = InstructionClv;
	_00412670[0xB8] = AddressingModeNop;
	// LDA - Absolute,Y
	_00412A70[0xB9] = 0x04;
	_00412270[0xB9] = InstructionLda;
	_00412670[0xB9] = AddressingModeAbsoluteY;
	// TSX
	_00412A70[0xBA] = 0x02;
	_00412270[0xBA] = InstructionTsx;
	_00412670[0xBA] = AddressingModeNop;
	// Future Expansion
	_00412A70[0xBB] = 0x02;
	_00412270[0xBB] = InstructionUnknown;
	_00412670[0xBB] = AddressingModeNop;
	// LDY - Absolute,X
	_00412A70[0xBC] = 0x04;
	_00412270[0xBC] = InstructionLdy;
	_00412670[0xBC] = AddressingModeAbsoluteX;
	// LDA - Absolute,X
	_00412A70[0xBD] = 0x04;
	_00412270[0xBD] = InstructionLda;
	_00412670[0xBD] = AddressingModeAbsoluteX;
	// LDX - Absolute,Y
	_00412A70[0xBE] = 0x04;
	_00412270[0xBE] = InstructionLdx;
	_00412670[0xBE] = AddressingModeAbsoluteY;
	// BBS3
	_00412A70[0xBF] = 0x02;
	_00412270[0xBF] = InstructionBbs3;
	_00412670[0xBF] = AddressingModeNone;
	// CPY - Immediate
	_00412A70[0xC0] = 0x03;
	_00412270[0xC0] = InstructionCpy;
	_00412670[0xC0] = AddressingModeImmediate;
	// CMP - (Indirect,X)
	_00412A70[0xC1] = 0x06;
	_00412270[0xC1] = InstructionCmp;
	_00412670[0xC1] = AddressingModeIndirectX;
	// Future Expansion
	_00412A70[0xC2] = 0x02;
	_00412270[0xC2] = InstructionUnknown;
	_00412670[0xC2] = AddressingModeNop;
	// Future Expansion
	_00412A70[0xC3] = 0x02;
	_00412270[0xC3] = InstructionUnknown;
	_00412670[0xC3] = AddressingModeNop;
	// CPY - Zero Page
	_00412A70[0xC4] = 0x03;
	_00412270[0xC4] = InstructionCpy;
	_00412670[0xC4] = AddressingModeZeroPage;
	// CMP - Zero Page
	_00412A70[0xC5] = 0x03;
	_00412270[0xC5] = InstructionCmp;
	_00412670[0xC5] = AddressingModeZeroPage;
	// DEC - Zero Page
	_00412A70[0xC6] = 0x05;
	_00412270[0xC6] = InstructionDec;
	_00412670[0xC6] = AddressingModeZeroPage;
	// Future Expansion
	_00412A70[0xC7] = 0x02;
	_00412270[0xC7] = InstructionUnknown;
	_00412670[0xC7] = AddressingModeNop;
	// INY
	_00412A70[0xC8] = 0x02;
	_00412270[0xC8] = InstructionIny;
	_00412670[0xC8] = AddressingModeNop;
	// CMP - Immediate
	_00412A70[0xC9] = 0x03;
	_00412270[0xC9] = InstructionCmp;
	_00412670[0xC9] = AddressingModeImmediate;
	// DEX
	_00412A70[0xCA] = 0x02;
	_00412270[0xCA] = InstructionDex;
	_00412670[0xCA] = AddressingModeNop;
	// Future Expansion
	_00412A70[0xCB] = 0x02;
	_00412270[0xCB] = InstructionUnknown;
	_00412670[0xCB] = AddressingModeNop;
	// CPY - Absolute
	_00412A70[0xCC] = 0x04;
	_00412270[0xCC] = InstructionCpy;
	_00412670[0xCC] = AddressingModeAbsolute;
	// CMP - Absolute
	_00412A70[0xCD] = 0x04;
	_00412270[0xCD] = InstructionCmp;
	_00412670[0xCD] = AddressingModeAbsolute;
	// DEC - Absolute
	_00412A70[0xCE] = 0x06;
	_00412270[0xCE] = InstructionDec;
	_00412670[0xCE] = AddressingModeAbsolute;
	// BBS4
	_00412A70[0xCF] = 0x02;
	_00412270[0xCF] = InstructionBbs4;
	_00412670[0xCF] = AddressingModeNone;
	// BNE
	_00412A70[0xD0] = 0x02;
	_00412270[0xD0] = InstructionBne;
	_00412670[0xD0] = AddressingModeNone;
	// CMP - (Indirect),Y
	_00412A70[0xD1] = 0x05;
	_00412270[0xD1] = InstructionCmp;
	_00412670[0xD1] = AddressingModeIndirectY;
	// Future Expansion
	_00412A70[0xD2] = 0x03;
	_00412270[0xD2] = InstructionUnknown;
	_00412670[0xD2] = AddressingModeNop;
	// Future Expansion
	_00412A70[0xD3] = 0x02;
	_00412270[0xD3] = InstructionUnknown;
	_00412670[0xD3] = AddressingModeNop;
	// Future Expansion
	_00412A70[0xD4] = 0x02;
	_00412270[0xD4] = InstructionUnknown;
	_00412670[0xD4] = AddressingModeNop;
	// CMP - Zero Page,X
	_00412A70[0xD5] = 0x04;
	_00412270[0xD5] = InstructionCmp;
	_00412670[0xD5] = AddressingModeZeroPageX;
	// DEC - Zero Page,X
	_00412A70[0xD6] = 0x06;
	_00412270[0xD6] = InstructionDec;
	_00412670[0xD6] = AddressingModeZeroPageX;
	// Future Expansion
	_00412A70[0xD7] = 0x02;
	_00412270[0xD7] = InstructionUnknown;
	_00412670[0xD7] = AddressingModeNop;
	// CLD
	_00412A70[0xD8] = 0x02;
	_00412270[0xD8] = InstructionCld;
	_00412670[0xD8] = AddressingModeNop;
	// CMP - Absolute,Y
	_00412A70[0xD9] = 0x04;
	_00412270[0xD9] = InstructionCmp;
	_00412670[0xD9] = AddressingModeAbsoluteY;
	// PHX
	_00412A70[0xDA] = 0x03;
	_00412270[0xDA] = InstructionPhx;
	_00412670[0xDA] = AddressingModeNop;
	// Future Expansion
	_00412A70[0xDB] = 0x02;
	_00412270[0xDB] = InstructionUnknown;
	_00412670[0xDB] = AddressingModeNop;
	// Future Expansion
	_00412A70[0xDC] = 0x02;
	_00412270[0xDC] = InstructionUnknown;
	_00412670[0xDC] = AddressingModeNop;
	// CMP - Absolute,X
	_00412A70[0xDD] = 0x04;
	_00412270[0xDD] = InstructionCmp;
	_00412670[0xDD] = AddressingModeAbsoluteX;
	// DEC - Absolute,X
	_00412A70[0xDE] = 0x07;
	_00412270[0xDE] = InstructionDec;
	_00412670[0xDE] = AddressingModeAbsoluteX;
	// BBS5
	_00412A70[0xDF] = 0x02;
	_00412270[0xDF] = InstructionBbs5;
	_00412670[0xDF] = AddressingModeNone;
	// CPX - Immediate
	_00412A70[0xE0] = 0x03;
	_00412270[0xE0] = InstructionCpx;
	_00412670[0xE0] = AddressingModeImmediate;
	// SBC - (Indirect,X)
	_00412A70[0xE1] = 0x06;
	_00412270[0xE1] = InstructionSbc;
	_00412670[0xE1] = AddressingModeIndirectX;
	// Future Expansion
	_00412A70[0xE2] = 0x02;
	_00412270[0xE2] = InstructionUnknown;
	_00412670[0xE2] = AddressingModeNop;
	// Future Expansion
	_00412A70[0xE3] = 0x02;
	_00412270[0xE3] = InstructionUnknown;
	_00412670[0xE3] = AddressingModeNop;
	// CPX - Zero Page
	_00412A70[0xE4] = 0x03;
	_00412270[0xE4] = InstructionCpx;
	_00412670[0xE4] = AddressingModeZeroPage;
	// SBC - Zero Page
	_00412A70[0xE5] = 0x03;
	_00412270[0xE5] = InstructionSbc;
	_00412670[0xE5] = AddressingModeZeroPage;
	// INC - Zero Page
	_00412A70[0xE6] = 0x05;
	_00412270[0xE6] = InstructionInc;
	_00412670[0xE6] = AddressingModeZeroPage;
	// Future Expansion
	_00412A70[0xE7] = 0x02;
	_00412270[0xE7] = InstructionUnknown;
	_00412670[0xE7] = AddressingModeNop;
	// INX
	_00412A70[0xE8] = 0x02;
	_00412270[0xE8] = InstructionInx;
	_00412670[0xE8] = AddressingModeNop;
	// SBC - Immediate
	_00412A70[0xE9] = 0x03;
	_00412270[0xE9] = InstructionSbc;
	_00412670[0xE9] = AddressingModeImmediate;
	// NOP
	_00412A70[0xEA] = 0x02;
	_00412270[0xEA] = InstructionNop;
	_00412670[0xEA] = AddressingModeNop;
	// Future Expansion
	_00412A70[0xEB] = 0x02;
	_00412270[0xEB] = InstructionUnknown;
	_00412670[0xEB] = AddressingModeNop;
	// CPX - Absolute
	_00412A70[0xEC] = 0x04;
	_00412270[0xEC] = InstructionCpx;
	_00412670[0xEC] = AddressingModeAbsolute;
	// SBC - Absolute
	_00412A70[0xED] = 0x04;
	_00412270[0xED] = InstructionSbc;
	_00412670[0xED] = AddressingModeAbsolute;
	// INC - Absolute
	_00412A70[0xEE] = 0x06;
	_00412270[0xEE] = InstructionInc;
	_00412670[0xEE] = AddressingModeAbsolute;
	// BBS6
	_00412A70[0xEF] = 0x02;
	_00412270[0xEF] = InstructionBbs6;
	_00412670[0xEF] = AddressingModeNone;
	// BEQ
	_00412A70[0xF0] = 0x02;
	_00412270[0xF0] = InstructionBeq;
	_00412670[0xF0] = AddressingModeNone;
	// SBC - (Indirect),Y
	_00412A70[0xF1] = 0x05;
	_00412270[0xF1] = InstructionSbc;
	_00412670[0xF1] = AddressingModeIndirectY;
	// Future Expansion
	_00412A70[0xF2] = 0x03;
	_00412270[0xF2] = InstructionUnknown;
	_00412670[0xF2] = AddressingModeNop;
	// Future Expansion
	_00412A70[0xF3] = 0x02;
	_00412270[0xF3] = InstructionUnknown;
	_00412670[0xF3] = AddressingModeNop;
	// Future Expansion
	_00412A70[0xF4] = 0x02;
	_00412270[0xF4] = InstructionUnknown;
	_00412670[0xF4] = AddressingModeNop;
	// SBC - Zero Page,X
	_00412A70[0xF5] = 0x04;
	_00412270[0xF5] = InstructionSbc;
	_00412670[0xF5] = AddressingModeZeroPageX;
	// INC - Zero Page,X
	_00412A70[0xF6] = 0x06;
	_00412270[0xF6] = InstructionInc;
	_00412670[0xF6] = AddressingModeZeroPageX;
	// Future Expansion
	_00412A70[0xF7] = 0x02;
	_00412270[0xF7] = InstructionUnknown;
	_00412670[0xF7] = AddressingModeNop;
	// SED
	_00412A70[0xF8] = 0x02;
	_00412270[0xF8] = InstructionSed;
	_00412670[0xF8] = AddressingModeNop;
	// SBC - Absolute,Y
	_00412A70[0xF9] = 0x04;
	_00412270[0xF9] = InstructionSbc;
	_00412670[0xF9] = AddressingModeAbsoluteY;
	// PLX
	_00412A70[0xFA] = 0x04;
	_00412270[0xFA] = InstructionPlx;
	_00412670[0xFA] = AddressingModeNop;
	// Future Expansion
	_00412A70[0xFB] = 0x02;
	_00412270[0xFB] = InstructionUnknown;
	_00412670[0xFB] = AddressingModeNop;
	// Future Expansion
	_00412A70[0xFC] = 0x02;
	_00412270[0xFC] = InstructionUnknown;
	_00412670[0xFC] = AddressingModeNop;
	// SBC - Absolute,X
	_00412A70[0xFD] = 0x04;
	_00412270[0xFD] = InstructionSbc;
	_00412670[0xFD] = AddressingModeAbsoluteX;
	// INC - Absolute,X
	_00412A70[0xFE] = 0x07;
	_00412270[0xFE] = InstructionInc;
	_00412670[0xFE] = AddressingModeAbsoluteX;
	// BBS7
	_00412A70[0xFF] = 0x02;
	_00412270[0xFF] = InstructionBbs7;
	_00412670[0xFF] = AddressingModeNone;

	for (int ebp_4=0; ebp_4<0x300; ebp_4++)
	{
		_004115FC[ebp_4] = ReadRegister;
		_00412E70[ebp_4] = WriteRegister;
	}
	_004115FC[0x000] = ReadAddr1;
	_004115FC[0x001] = ReadAddr2;
	_004115FC[0x002] = ReadAddr3;
	_004115FC[0x003] = ReadAddr4;
	_004115FC[0x004] = ReadRegister;
	_004115FC[0x005] = ReadRegister;
	_004115FC[0x006] = ReadRegister;
	_004115FC[0x007] = ReadRegister;
	_004115FC[0x008] = ReadSBuf;
	_004115FC[0x009] = ReadRegister;
	_004115FC[0x00A] = ReadRegister;
	_004115FC[0x00B] = ReadRegister;
	_004115FC[0x00C] = ReadBkSel;
	_004115FC[0x00D] = ReadBkAdrL;
	_004115FC[0x00E] = ReadBkAdrH;
	_004115FC[0x00F] = ReadRegister;
	_004115FC[0x010] = ReadRegister;
	_004115FC[0x011] = ReadRegister;
	_004115FC[0x012] = ReadRegister;
	_004115FC[0x013] = ReadRegister;
	_004115FC[0x014] = ReadRegister;
	_004115FC[0x015] = ReadRegister;
	_004115FC[0x016] = ReadRegister;
	_004115FC[0x017] = ReadRegister;
	_004115FC[0x018] = ReadRegister;
	_004115FC[0x019] = ReadRegister;
	_004115FC[0x01A] = ReadRegister;
	_004115FC[0x01B] = ReadRegister;
	_004115FC[0x01C] = ReadRegister;
	_004115FC[0x01D] = ReadRegister;
	_004115FC[0x01E] = ReadRegister;
	_004115FC[0x01F] = ReadRegister;

	_004115FC[0x200] = ReadRegister;
	_004115FC[0x201] = ReadRegister;
	_004115FC[0x202] = ReadRegister;
	_004115FC[0x203] = ReadRegister;
	_004115FC[0x204] = ReadRegister;
	_004115FC[0x205] = ReadRegister;
	_004115FC[0x206] = ReadRegister;
	_004115FC[0x207] = ReadRegister;
	_004115FC[0x208] = ReadRegister;
	_004115FC[0x209] = ReadRegister;
	_004115FC[0x20A] = ReadRegister;
	_004115FC[0x20B] = ReadRegister;
	_004115FC[0x20C] = ReadRegister;
	_004115FC[0x20D] = ReadRegister;
	_004115FC[0x20E] = ReadRegister;
	_004115FC[0x20F] = ReadRegister;
	_004115FC[0x210] = ReadRegister;
	_004115FC[0x211] = ReadRegister;
	_004115FC[0x212] = ReadRegister;
	_004115FC[0x213] = ReadRegister;
	_004115FC[0x214] = ReadRegister;
	_004115FC[0x215] = ReadRegister;
	_004115FC[0x216] = ReadRegister;
	_004115FC[0x217] = ReadRegister;
	_004115FC[0x218] = ReadRegister;
	_004115FC[0x219] = ReadRegister;
	_004115FC[0x21A] = ReadRegister;
	_004115FC[0x21B] = ReadRegister;
	_004115FC[0x21C] = ReadRegister;
	_004115FC[0x21D] = ReadRegister;
	_004115FC[0x21E] = ReadRegister;
	_004115FC[0x21F] = ReadRegister;
	_004115FC[0x220] = ReadRegister;
	_004115FC[0x221] = ReadRegister;
	_004115FC[0x222] = ReadRegister;
	_004115FC[0x223] = ReadRegister;
	_004115FC[0x224] = ReadRegister;
	_004115FC[0x225] = ReadRegister;
	_004115FC[0x226] = ReadRegister;
	_004115FC[0x227] = ReadRegister;
	_004115FC[0x228] = ReadRegister;
	_004115FC[0x229] = ReadRegister;
	_004115FC[0x22A] = ReadRegister;
	_004115FC[0x22B] = ReadRegister;
	_004115FC[0x22C] = ReadRegister;
	_004115FC[0x22D] = ReadRegister;
	_004115FC[0x22E] = ReadRegister;
	_004115FC[0x22F] = ReadRegister;
	_004115FC[0x230] = ReadRegister;
	_004115FC[0x231] = ReadRegister;
	_004115FC[0x232] = ReadRegister;
	_004115FC[0x233] = ReadRegister;
	_004115FC[0x234] = ReadRegister;
	_004115FC[0x235] = ReadRegister;
	_004115FC[0x236] = ReadRegister;
	_004115FC[0x237] = ReadRegister;
	_004115FC[0x238] = ReadRegister;
	_004115FC[0x239] = ReadRegister;
	_004115FC[0x23A] = ReadRegister;
	_004115FC[0x23B] = ReadRegister;
	_004115FC[0x23C] = ReadRegister;
	_004115FC[0x23D] = ReadRegister;
	_004115FC[0x23E] = ReadRegister;
	_004115FC[0x23F] = ReadRegister;
	_004115FC[0x240] = ReadRegister;
	_004115FC[0x241] = ReadRegister;
	_004115FC[0x242] = ReadRegister;
	_004115FC[0x243] = ReadRegister;
	_004115FC[0x244] = ReadUrCon1;
	_004115FC[0x245] = ReadRegister;
	_004115FC[0x246] = ReadRegister;
	_004115FC[0x247] = ReadRegister;
	_004115FC[0x248] = ReadRegister;
	_004115FC[0x249] = ReadRegister;
	_004115FC[0x24A] = ReadRegister;
	_004115FC[0x24B] = ReadRegister;
	_004115FC[0x24C] = ReadRegister;
	_004115FC[0x24D] = ReadRegister;
	_004115FC[0x24E] = ReadRegister;
	_004115FC[0x24F] = ReadRegister;
	_004115FC[0x250] = ReadRegister;
	_004115FC[0x251] = ReadRegister;
	_004115FC[0x252] = ReadRegister;
	_004115FC[0x253] = ReadRegister;
	_004115FC[0x254] = ReadRegister;
	_004115FC[0x255] = ReadRegister;
	_004115FC[0x256] = ReadRegister;
	_004115FC[0x257] = ReadRegister;
	_004115FC[0x258] = ReadRegister;
	_004115FC[0x259] = ReadRegister;
	_004115FC[0x25A] = ReadRegister;
	_004115FC[0x25B] = ReadRegister;
	_004115FC[0x25C] = ReadRegister;
	_004115FC[0x25D] = ReadRegister;
	_004115FC[0x25E] = ReadRegister;
	_004115FC[0x25F] = ReadRegister;
	_004115FC[0x260] = ReadRegister;
	_004115FC[0x261] = ReadRegister;
	_004115FC[0x262] = ReadRegister;

	_00412E70[0x000] = WriteAddr1;
	_00412E70[0x001] = WriteAddr2;
	_00412E70[0x002] = WriteAddr3;
	_00412E70[0x003] = WriteAddr4;
	_00412E70[0x004] = WriteIsr;
	_00412E70[0x005] = WriteTIsr;
	_00412E70[0x006] = WriteRegister;
	_00412E70[0x007] = WriteRegister;
	_00412E70[0x008] = WriteSBuf;
	_00412E70[0x009] = WriteRegister;
	_00412E70[0x00A] = WriteRegister;
	_00412E70[0x00B] = WriteRegister;
	_00412E70[0x00C] = WriteBkSel;
	_00412E70[0x00D] = WriteBkAdrL;
	_00412E70[0x00E] = WriteBkAdrH;
	_00412E70[0x00F] = WriteRegister;
	_00412E70[0x010] = WriteRegister;
	_00412E70[0x011] = WriteRegister;
	_00412E70[0x012] = WriteRegister;
	_00412E70[0x013] = WriteRegister;
	_00412E70[0x014] = WriteRegister;
	_00412E70[0x015] = WriteRegister;
	_00412E70[0x016] = WriteRegister;
	_00412E70[0x017] = WriteRegister;
	_00412E70[0x018] = WriteRegister;
	_00412E70[0x019] = WriteRegister;
	_00412E70[0x01A] = WriteRegister;
	_00412E70[0x01B] = WriteRegister;
	_00412E70[0x01C] = WriteRegister;
	_00412E70[0x01D] = WriteRegister;
	_00412E70[0x01E] = WriteRegister;
	_00412E70[0x01F] = WriteRegister;

	_00412E70[0x200] = WriteSysCon;
	_00412E70[0x201] = WriteRegister;
	_00412E70[0x202] = WriteRegister;
	_00412E70[0x203] = WriteRegister;
	_00412E70[0x204] = WriteRegister;
	_00412E70[0x205] = WriteRegister;
	_00412E70[0x206] = WriteRegister;
	_00412E70[0x207] = WriteRegister;
	_00412E70[0x208] = WriteRegister;
	_00412E70[0x209] = WriteRegister;
	_00412E70[0x20A] = WriteRegister;
	_00412E70[0x20B] = WriteRegister;
	_00412E70[0x20C] = WriteRegister;
	_00412E70[0x20D] = WriteRegister;
	_00412E70[0x20E] = WriteRegister;
	_00412E70[0x20F] = WriteRegister;
	_00412E70[0x210] = WriteRegister;
	_00412E70[0x211] = WriteRegister;
	_00412E70[0x212] = WriteRegister;
	_00412E70[0x213] = WriteRegister;
	_00412E70[0x214] = WriteRegister;
	_00412E70[0x215] = WriteRegister;
	_00412E70[0x216] = WriteRegister;
	_00412E70[0x217] = WriteRegister;
	_00412E70[0x218] = WriteRegister;
	_00412E70[0x219] = WriteRegister;
	_00412E70[0x21A] = WriteRegister;
	_00412E70[0x21B] = WriteRegister;
	_00412E70[0x21C] = WriteRegister;
	_00412E70[0x21D] = WriteRegister;
	_00412E70[0x21E] = WriteRegister;
	_00412E70[0x21F] = WriteRegister;
	_00412E70[0x220] = WriteRegister;
	_00412E70[0x221] = WriteRegister;
	_00412E70[0x222] = WriteRegister;
	_00412E70[0x223] = WriteRegister;
	_00412E70[0x224] = WriteRegister;
	_00412E70[0x225] = WriteRegister;
	_00412E70[0x226] = WriteRegister;
	_00412E70[0x227] = WriteRegister;
	_00412E70[0x228] = WriteRegister;
	_00412E70[0x229] = WriteRegister;
	_00412E70[0x22A] = WriteRegister;
	_00412E70[0x22B] = WriteRegister;
	_00412E70[0x22C] = WriteRegister;
	_00412E70[0x22D] = WriteRegister;
	_00412E70[0x22E] = WriteRegister;
	_00412E70[0x22F] = WriteRegister;
	_00412E70[0x230] = WriteRegister;
	_00412E70[0x231] = WriteRegister;
	_00412E70[0x232] = WriteRegister;
	_00412E70[0x233] = WriteRegister;
	_00412E70[0x234] = WriteRegister;
	_00412E70[0x235] = WriteRegister;
	_00412E70[0x236] = WriteRegister;
	_00412E70[0x237] = WriteRegister;
	_00412E70[0x238] = WriteRegister;
	_00412E70[0x239] = WriteRegister;
	_00412E70[0x23A] = WriteRegister;
	_00412E70[0x23B] = WriteRegister;
	_00412E70[0x23C] = WriteRegister;
	_00412E70[0x23D] = WriteRegister;
	_00412E70[0x23E] = WriteRegister;
	_00412E70[0x23F] = WriteRegister;
	_00412E70[0x240] = WriteRegister;
	_00412E70[0x241] = WriteRegister;
	_00412E70[0x242] = WriteRegister;
	_00412E70[0x243] = WriteRegister;
	_00412E70[0x244] = WriteUsCon1;
	_00412E70[0x245] = WriteRegister;
	_00412E70[0x246] = WriteRegister;
	_00412E70[0x247] = WriteRegister;
	_00412E70[0x248] = WriteRegister;
	_00412E70[0x249] = WriteRegister;
	_00412E70[0x24A] = WriteRegister;
	_00412E70[0x24B] = WriteRegister;
	_00412E70[0x24C] = WriteRegister;
	_00412E70[0x24D] = WriteRegister;
	_00412E70[0x24E] = WriteRegister;
	_00412E70[0x24F] = WriteRegister;
	_00412E70[0x250] = WriteRegister;
	_00412E70[0x251] = WriteRegister;
	_00412E70[0x252] = WriteRegister;
	_00412E70[0x253] = WriteRegister;
	_00412E70[0x254] = WriteRegister;
	_00412E70[0x255] = WriteRegister;
	_00412E70[0x256] = WriteRegister;
	_00412E70[0x257] = WriteRegister;
	_00412E70[0x258] = WriteRegister;
	_00412E70[0x259] = WriteRegister;
	_00412E70[0x25A] = WriteRegister;
	_00412E70[0x25B] = WriteRegister;
	_00412E70[0x25C] = WriteRegister;
	_00412E70[0x25D] = WriteRegister;
	_00412E70[0x25E] = WriteRegister;
	_00412E70[0x25F] = WriteRegister;
	_00412E70[0x260] = WriteRegister;
	_00412E70[0x261] = WriteRegister;
	_00412E70[0x262] = WriteRegister;
}

// 设置寄存器默认状态
void _0040B7A9()
{
    *(UINT32*)(pRam+0x1B) |= 0x20;
    *(UINT32*)(pRam+0x1B) |= 0x40;
    *(UINT32*)(pRam+0x1B) |= 0x80;
    pRam[0x202] = 0x6C;
    *(UINT32*)(pRam+0x203) |= 0x40;
    *(UINT32*)(pRam+0x207) |= 0x01;
    *(UINT32*)(pRam+0x207) |= 0x02;
    *(UINT32*)(pRam+0x207) |= 0x04;
    *(UINT32*)(pRam+0x207) |= 0x08;
    pRam[0x215] = 0xFF;
    pRam[0x219] = 0xFF;
    pRam[0x21C] = 0xFF;
    pRam[0x220] = 0x08;
    *(UINT32*)(pRam+0x222) |= 0x04;
    *(UINT32*)(pRam+0x222) |= 0x40;
    *(UINT32*)(pRam+0x22E) |= 0x01;
    *(UINT32*)(pRam+0x22E) &= 0xFFFFFFDF;
    *(UINT32*)(pRam+0x24B) |= 0x01;
    *(UINT32*)(pRam+0x24B) |= 0x04;
    *(UINT32*)(pRam+0x25B) |= 0x20;
    *(UINT32*)(pRam+0x25B) |= 0x40;
    *(UINT32*)(pRam+0x25B) |= 0x80;
}

// 重置MCU状态
void _0040B995()
{
    cpu.A = 0;
    cpu.X = 0;
    cpu.Y = 0;
    cpu.P = 0x20;
    cpu.S = 0x1FF;
    cpu.PC = 0x350;
    Timer1Counter = 0;
    Timer2Counter = 0;
    Timer3Counter = 0;
    Timer4Counter = 0;
    _00412200 = 0;
}

// done
BOOL _0040BA15()
{
    _00408F04();
    _0040B995();
    return TRUE;
}

// done
UINT32 _0040BA29(UINT32 v1)
{
    return BankAddressList[v1];
}

// done
void _0040BA38()
{
    _00412200 = 0;
	_00413A78 = _00413A74;
	cpu.PC++;
}

// done
void _0040BA60()
{
    UINT32 ebp_4 = BankAddressList[cpu.PC >> 0x0C] | (cpu.PC & 0x0FFF);
    _00413A78 = _00410C50[ebp_4 >> 0x13][ebp_4 & 0x7FFFF];
    cpu.PC++;
}

// done
void _0040BAB7()
{
#ifdef _DEBUG
    UINT32 address = BankAddressList[cpu.PC >> 0x0C] | (cpu.PC & 0x0FFF);
	regedits[regedits_index].A = cpu.A;
	regedits[regedits_index].S = cpu.S;
	regedits[regedits_index].X = cpu.X;
	regedits[regedits_index].Y = cpu.Y;
	regedits[regedits_index].P = cpu.P;
	regedits[regedits_index].PC = cpu.PC;
	regedits[regedits_index].opcode = _00410C50[address >> 0x13][address & 0x7FFFF];
	regedits[regedits_index].datas[0] = _00410C50[(address+1)>>0x13][(address+1)&0x7FFFF];
	regedits[regedits_index].datas[1] = _00410C50[(address+2)>>0x13][(address+2)&0x7FFFF];
	regedits[regedits_index].datas[2] = _00410C50[(address+3)>>0x13][(address+3)&0x7FFFF];
	regedits[regedits_index].counter = CycleCounter;
	regedits_index++;
	if (cpu.PC == 0x7166)
	{
		printf("%d", cpu.PC);
	}
#endif
    UINT32 ebp_4 = BankAddressList[cpu.PC >> 0x0C] | (cpu.PC & 0x0FFF);
    _00413A78 = _00410C50[ebp_4 >> 0x13][ebp_4 & 0x7FFFF]; // opcode
    cpu.PC++;
    CycleCounter += _00412A70[_00413A78];
    _00412670[_00413A78]();
    _00412270[_00413A78]();
    pInterruptHandle[bWantInt](); // _00413A90为1进中断
}

// 中断响应函数
void InterruptHandle()
{
	if (cpu.P&0x04)
	{
		return; // 软中断
	}
	bWantInt = 0;
	UINT32 ebp_4 = 0xFF;
	if ((*(UINT32*)(pRam+0x05) & 0x08) && (*(UINT32*)(pRam+0x23B) & 0x08))
	{
		ebp_4 = 0x06;
	}
	if ((*(UINT32*)(pRam+0x05) & 0x04) && (*(UINT32*)(pRam+0x23B) & 0x04))
	{
		ebp_4 = 0x05;
	}
	if ((*(UINT32*)(pRam+0x05) & 0x02) && (*(UINT32*)(pRam+0x23B) & 0x02))
	{
		ebp_4 = 0x04;
	}
	if ((*(UINT32*)(pRam+0x05) & 0x01) && (*(UINT32*)(pRam+0x23B) & 0x01))
	{
		ebp_4 = 0x03;
	}
	if ((*(UINT32*)(pRam+0x04) & 0x02) && (*(UINT32*)(pRam+0x23A) & 0x02))
	{
		ebp_4 = 0x12;
	}
	if (*(UINT32*)(pRam+0x09) & 0x40)
	{
		ebp_4 = 0x0C;
	}
	if ((*(UINT32*)(pRam+0x04) & 0x80) && (*(UINT32*)(pRam+0x23A) & 0x80))
	{
		ebp_4 = 0x02;
	}
	if ((*(UINT32*)(pRam+0x04) & 0x01) && (*(UINT32*)(pRam+0x23A) & 0x01))
	{
		ebp_4 = 0x13;
	}
	if (ebp_4 == 0xFF)
	{
		return;
	}
	cpu.S -= 0x03;
	*(UINT32*)(pRam+cpu.S) = (cpu.PC<<0x10) | (cpu.P<<0x08);
	cpu.PC = ebp_4*4+0x300;
	cpu.P |= 0x04;
}

// MCU定时器模拟
void _0040BD0B(UINT32 v1)
{
    if (_0040E3F8 == 0)
    {
        return;
    }
    if (*(UINT32*)(pRam+0x226) & 0x01) // _STCON
    {
        Timer1Counter += v1;
        if (Timer1Counter >= 0x100)
        {
            if (*(UINT32*)(pRam+0x23B) & 0x01) // _TIER
            {
                *(UINT32*)(pRam+0x05) |= 0x01; // _TISR
                bWantInt = 0x01;
                SleepFlag = 0x00;
            }
            Timer1Counter = pRam[0x227]; // _ST1LD
        }
    }
    if (*(UINT32*)(pRam+0x226) & 0x02)
    {
        Timer2Counter += v1;
        if (Timer2Counter >= 0x100)
        {
            if (*(UINT32*)(pRam+0x23B) & 0x02)
            {
                *(UINT32*)(pRam+0x05) |= 0x02;
                bWantInt = 0x01;
                SleepFlag = 0x00;
            }
            Timer2Counter = pRam[0x228]; // _ST2LD
        }
    }
    if (*(UINT32*)(pRam+0x226) & 0x04)
    {
        Timer3Counter += v1;
        if (Timer3Counter >= 0x100)
        {
            if (*(UINT32*)(pRam+0x23B) & 0x04)
            {
                *(UINT32*)(pRam+0x05) |= 0x04;
                bWantInt = 0x01;
                SleepFlag = 0x00;
            }
            Timer3Counter = pRam[0x229]; // _ST3LD
        }
    }
    if (*(UINT32*)(pRam+0x226) & 0x08)
    {
        Timer4Counter += v1;
        if (Timer4Counter >= 0x100)
        {
            if (*(UINT32*)(pRam+0x23B) & 0x08)
            {
                *(UINT32*)(pRam+0x05) |= 0x08;
                bWantInt = 0x01;
                SleepFlag = 0x00;
            }
            Timer4Counter = pRam[0x22A]; // _ST4LD
        }
    }
    if (*(UINT32*)(pRam+0x22E) & 0x10) // _STCTCON
    {
        UniversalTimerCounter += v1;
        if (UniversalTimerCounter >= 0x1000)
        {
            if (*(UINT32*)(pRam+0x23A) & 0x02) // _IER
            {
                *(UINT32*)(pRam+0x04) |= 0x02;
                bWantInt = 0x01;
                SleepFlag = 0x00;
            }
            UniversalTimerCounter = pRam[0x22F]; // _CTLD
        }
    }
}

// done
void _0040BF83()
{
    if ((*(UINT32*)(pRam+0x22E) & 0x40) == 0x00)
	{
		return;
	}
    if (pRam[0x234]++ == 59) // _RTCSEC
    {
        pRam[0x234] = 0;
        if (pRam[0x235]++ == 59) // _RTCMIN
        {
            pRam[0x235] = 0;
            if (pRam[0x236]++ == 23) // _RTCHR
            {
                pRam[0x236] = 0;
                if (pRam[0x237]++ == 0xFF) // _RTCDAYL
                {
                    if (pRam[0x238]++ == 1) // _RTCDAYH
                    {
                        pRam[0x238] = 0;
                    }
                }
            }
        }
    }
    if ((*(UINT32*)(pRam+0x22E) & 0x20) == 0x00) // _STCTCON
	{
		return;
	}
	// 闹钟时间是否到
    if ((pRam[0x235] == pRam[0x230]) // _RTCMIN == _ALMMIN
        && (pRam[0x236] == pRam[0x231]) // _RTCHR == _ALMHR
        && (pRam[0x232] == pRam[0x232])
        && (pRam[0x233] == pRam[0x233]))
    {
        *(UINT32*)(pRam+0x04) |= 0x01; // _ISR
    }
}

// done
UINT32 MCU_GetPhysicalPC(UINT32 v1)
{
    return BankAddressList[v1>>0x0C]| (v1&0x0FFF);
}

// 读数据
void _0040C190()
{
    _00413A70 = BankAddressList[_004121FC>>0x0C] | (_004121FC&0x0FFF);
	if (_00413A70 < 0x300)
	{
		_004115FC[_00413A70]();
	}
	else
	{
		_0040569A();
	}
}

// 写数据
void _0040C1E0()
{
    _00413A70 = BankAddressList[_004121FC>>0x0C] | (_004121FC&0x0FFF);
	if (_00413A70 < 0x300)
	{
		_00412E70[_00413A70]();
	}
	else
	{
		_004057C3();
	}
}

#ifdef _DEBUG
void debug_save_regedits()
{
	char buffer[0x100];
	FILE *fp= fopen("regedits.log", "w");
	for (int i=0; i<0x100; i++)
	{
		struct _REGEDIT regedit = regedits[(UINT8)(regedits_index+i)];
		sprintf(buffer, "A:%02X S:%04X X:%02X Y:%02X P:%02X\n[%02X %02X %02X %02X] ",
			regedit.A, regedit.S, regedit.X, regedit.Y, regedit.P,
			regedit.opcode, regedit.datas[0], regedit.datas[1], regedit.datas[2]);
		UINT32 pc = regedit.PC;
		DBG_Disassembly(&pc, buffer+strlen(buffer), 0, NULL);
		fwrite(buffer, 1, strlen(buffer), fp);
		fwrite("\n", 1, 1, fp);
	}
	fclose(fp);
}
#endif